GAIAGEO_DECLARE void gaiaScaleCoords (gaiaGeomCollPtr geom, double scale_x, double scale_y) { /* returns a geometry that is the old geometry with required scaling applied to coordinates */ int ib; int iv; double x; double y; double z; double m; gaiaPointPtr point; gaiaPolygonPtr polyg; gaiaLinestringPtr line; gaiaRingPtr ring; if (!geom) return; point = geom->FirstPoint; while (point) { /* scaling POINTs */ point->X *= scale_x; point->Y *= scale_y; point = point->Next; } line = geom->FirstLinestring; while (line) { /* scaling LINESTRINGs */ for (iv = 0; iv < line->Points; iv++) { if (line->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (line->Coords, iv, &x, &y); } x *= scale_x; y *= scale_y; if (line->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (line->Coords, iv, x, y, z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (line->Coords, iv, x, y, m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (line->Coords, iv, x, y, z, m); } else { gaiaSetPoint (line->Coords, iv, x, y); } } line = line->Next; } polyg = geom->FirstPolygon; while (polyg) { /* scaling POLYGONs */ ring = polyg->Exterior; for (iv = 0; iv < ring->Points; iv++) { /* scaling the EXTERIOR RING */ if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } x *= scale_x; y *= scale_y; if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } for (ib = 0; ib < polyg->NumInteriors; ib++) { /* scaling the INTERIOR RINGs */ ring = polyg->Interiors + ib; for (iv = 0; iv < ring->Points; iv++) { if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } x *= scale_x; y *= scale_y; if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } } polyg = polyg->Next; } gaiaMbrGeometry (geom); }
GAIAGEO_DECLARE void gaiaShiftLongitude (gaiaGeomCollPtr geom) { /* returns a geometry that is the old geometry with negative longitudes shift by 360 */ int ib; int iv; double x; double y; double z; double m; gaiaPointPtr point; gaiaPolygonPtr polyg; gaiaLinestringPtr line; gaiaRingPtr ring; if (!geom) return; point = geom->FirstPoint; while (point) { /* shifting POINTs */ if (point->X < 0) { point->X += 360.0; } point = point->Next; } line = geom->FirstLinestring; while (line) { /* shifting LINESTRINGs */ for (iv = 0; iv < line->Points; iv++) { if (line->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (line->Coords, iv, &x, &y); } if (x < 0) { x += 360.0; } if (line->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (line->Coords, iv, x, y, z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (line->Coords, iv, x, y, m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (line->Coords, iv, x, y, z, m); } else { gaiaSetPoint (line->Coords, iv, x, y); } } line = line->Next; } polyg = geom->FirstPolygon; while (polyg) { /* shifting POLYGONs */ ring = polyg->Exterior; for (iv = 0; iv < ring->Points; iv++) { /* shifting the EXTERIOR RING */ if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } if (x < 0) { x += 360.0; } if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } for (ib = 0; ib < polyg->NumInteriors; ib++) { /* shifting the INTERIOR RINGs */ ring = polyg->Interiors + ib; for (iv = 0; iv < ring->Points; iv++) { if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } if (x < 0) { x += 360.0; } if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } } polyg = polyg->Next; } gaiaMbrGeometry (geom); }
GAIAGEO_DECLARE void gaiaNormalizeLonLat (gaiaGeomCollPtr geom) { /* returns a geometry that is the old geometry with all latitudes shifted into the range -90 to 90, and all longitudes shifted into the range -180 to 180. */ int ib; int iv; double x; double y; double z; double m; gaiaPointPtr point; gaiaPolygonPtr polyg; gaiaLinestringPtr line; gaiaRingPtr ring; if (!geom) return; point = geom->FirstPoint; while (point) { normalizePoint (&(point->X), &(point->Y)); point = point->Next; } line = geom->FirstLinestring; while (line) { /* shifting LINESTRINGs */ for (iv = 0; iv < line->Points; iv++) { if (line->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (line->Coords, iv, &x, &y); } normalizePoint (&x, &y); if (line->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (line->Coords, iv, x, y, z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (line->Coords, iv, x, y, m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (line->Coords, iv, x, y, z, m); } else { gaiaSetPoint (line->Coords, iv, x, y); } } line = line->Next; } polyg = geom->FirstPolygon; while (polyg) { /* shifting POLYGONs */ ring = polyg->Exterior; for (iv = 0; iv < ring->Points; iv++) { /* shifting the EXTERIOR RING */ if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } normalizePoint (&x, &y); if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } for (ib = 0; ib < polyg->NumInteriors; ib++) { /* shifting the INTERIOR RINGs */ ring = polyg->Interiors + ib; for (iv = 0; iv < ring->Points; iv++) { if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } normalizePoint (&x, &y); if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } } polyg = polyg->Next; } gaiaMbrGeometry (geom); }
GAIAGEO_DECLARE void gaiaSwapCoords (gaiaGeomCollPtr geom) { /* returns a geometry that is the old geometry with swapped x- and y-coordinates */ int ib; int iv; double x; double y; double z; double m; double sv; gaiaPointPtr point; gaiaPolygonPtr polyg; gaiaLinestringPtr line; gaiaRingPtr ring; if (!geom) return; point = geom->FirstPoint; while (point) { /* swapping POINTs */ sv = point->X; point->X = point->Y; point->Y = sv; point = point->Next; } line = geom->FirstLinestring; while (line) { /* swapping LINESTRINGs */ for (iv = 0; iv < line->Points; iv++) { if (line->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (line->Coords, iv, &x, &y); } sv = x; x = y; y = sv; if (line->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (line->Coords, iv, x, y, z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (line->Coords, iv, x, y, m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (line->Coords, iv, x, y, z, m); } else { gaiaSetPoint (line->Coords, iv, x, y); } } line = line->Next; } polyg = geom->FirstPolygon; while (polyg) { /* swapping POLYGONs */ ring = polyg->Exterior; for (iv = 0; iv < ring->Points; iv++) { /* shifting the EXTERIOR RING */ if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } sv = x; x = y; y = sv; if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } for (ib = 0; ib < polyg->NumInteriors; ib++) { /* swapping the INTERIOR RINGs */ ring = polyg->Interiors + ib; for (iv = 0; iv < ring->Points; iv++) { if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } sv = x; x = y; y = sv; if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, x, y, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, x, y, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, x, y, z, m); } else { gaiaSetPoint (ring->Coords, iv, x, y); } } } polyg = polyg->Next; } gaiaMbrGeometry (geom); }
static gaiaGeomCollPtr gaiaTransformCommon (projCtx handle, gaiaGeomCollPtr org, char *proj_from, char *proj_to) { /* creates a new GEOMETRY reprojecting coordinates from the original one */ int ib; int cnt; int i; double *xx; double *yy; double *zz; double *mm = NULL; double x; double y; double z = 0.0; double m = 0.0; int error = 0; int from_angle; int to_angle; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaLinestringPtr dst_ln; gaiaPolygonPtr pg; gaiaPolygonPtr dst_pg; gaiaRingPtr rng; gaiaRingPtr dst_rng; projPJ from_cs; projPJ to_cs; gaiaGeomCollPtr dst; if (handle != NULL) { from_cs = pj_init_plus_ctx (handle, proj_from); to_cs = pj_init_plus_ctx (handle, proj_to); } else { from_cs = pj_init_plus (proj_from); to_cs = pj_init_plus (proj_to); } if (!from_cs) { if (to_cs) pj_free (to_cs); return NULL; } if (!to_cs) { pj_free (from_cs); return NULL; } if (org->DimensionModel == GAIA_XY_Z) dst = gaiaAllocGeomCollXYZ (); else if (org->DimensionModel == GAIA_XY_M) dst = gaiaAllocGeomCollXYM (); else if (org->DimensionModel == GAIA_XY_Z_M) dst = gaiaAllocGeomCollXYZM (); else dst = gaiaAllocGeomColl (); /* setting up projection parameters */ from_angle = gaiaIsLongLat (proj_from); to_angle = gaiaIsLongLat (proj_to); cnt = 0; pt = org->FirstPoint; while (pt) { /* counting POINTs */ cnt++; pt = pt->Next; } if (cnt) { /* reprojecting POINTs */ xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); i = 0; pt = org->FirstPoint; while (pt) { /* inserting points to be converted in temporary arrays */ if (from_angle) { xx[i] = gaiaDegsToRads (pt->X); yy[i] = gaiaDegsToRads (pt->Y); } else { xx[i] = pt->X; yy[i] = pt->Y; } if (org->DimensionModel == GAIA_XY_Z || org->DimensionModel == GAIA_XY_Z_M) zz[i] = pt->Z; else zz[i] = 0.0; if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) mm[i] = pt->M; i++; pt = pt->Next; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POINTs in the new GEOMETRY */ for (i = 0; i < cnt; i++) { if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (org->DimensionModel == GAIA_XY_Z || org->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (dst, x, y, z); else if (dst->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (dst, x, y, m); else if (dst->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (dst, x, y, z, m); else gaiaAddPointToGeomColl (dst, x, y); } } else error = 1; free (xx); free (yy); free (zz); if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) free (mm); } if (error) goto stop; ln = org->FirstLinestring; while (ln) { /* reprojecting LINESTRINGs */ cnt = ln->Points; xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays */ if (ln->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ln->Coords, i, &x, &y, &z); } else if (ln->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ln->Coords, i, &x, &y, &m); } else if (ln->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ln->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (ln->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected LINESTRING in the new GEOMETRY */ dst_ln = gaiaAddLinestringToGeomColl (dst, cnt); for (i = 0; i < cnt; i++) { /* setting LINESTRING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_ln->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_ln->Coords, i, x, y, z); } else if (dst_ln->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_ln->Coords, i, x, y, m); } else if (dst_ln->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_ln->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_ln->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; ln = ln->Next; } pg = org->FirstPolygon; while (pg) { /* reprojecting POLYGONs */ rng = pg->Exterior; cnt = rng->Points; dst_pg = gaiaAddPolygonToGeomColl (dst, cnt, pg->NumInteriors); xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays [EXTERIOR RING] */ if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, i, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, i, &x, &y, &m); } else if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (rng->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POLYGON in the new GEOMETRY */ dst_rng = dst_pg->Exterior; for (i = 0; i < cnt; i++) { /* setting EXTERIOR RING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_rng->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z); } else if (dst_rng->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_rng->Coords, i, x, y, m); } else if (dst_rng->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_rng->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_rng->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; for (ib = 0; ib < pg->NumInteriors; ib++) { /* processing INTERIOR RINGS */ rng = pg->Interiors + ib; cnt = rng->Points; xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays [INTERIOR RING] */ if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, i, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, i, &x, &y, &m); } else if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (rng->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POLYGON in the new GEOMETRY */ dst_rng = gaiaAddInteriorRing (dst_pg, ib, cnt); for (i = 0; i < cnt; i++) { /* setting INTERIOR RING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_rng->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z); } else if (dst_rng->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_rng->Coords, i, x, y, m); } else if (dst_rng->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_rng->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_rng->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; } pg = pg->Next; } /* destroying the PROJ4 params */ stop: pj_free (from_cs); pj_free (to_cs); if (error) { /* some error occurred */ gaiaPointPtr pP; gaiaPointPtr pPn; gaiaLinestringPtr pL; gaiaLinestringPtr pLn; gaiaPolygonPtr pA; gaiaPolygonPtr pAn; pP = dst->FirstPoint; while (pP != NULL) { pPn = pP->Next; gaiaFreePoint (pP); pP = pPn; } pL = dst->FirstLinestring; while (pL != NULL) { pLn = pL->Next; gaiaFreeLinestring (pL); pL = pLn; } pA = dst->FirstPolygon; while (pA != NULL) { pAn = pA->Next; gaiaFreePolygon (pA); pA = pAn; } dst->FirstPoint = NULL; dst->LastPoint = NULL; dst->FirstLinestring = NULL; dst->LastLinestring = NULL; dst->FirstPolygon = NULL; dst->LastPolygon = NULL; } if (dst) { gaiaMbrGeometry (dst); dst->DeclaredType = org->DeclaredType; } return dst; }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaSanitize (gaiaGeomCollPtr geom) { /* / sanitizes a GEOMETRYCOLLECTION: / - repeated vertices are omitted / - ring closure is enforced anyway */ int iv; int ib; double x = 0.0; double y = 0.0; double z = 0.0; double m = 0.0; double last_x = 0.0; double last_y = 0.0; double last_z = 0.0; int points; gaiaPointPtr point; gaiaLinestringPtr line; gaiaLinestringPtr new_line; gaiaPolygonPtr polyg; gaiaPolygonPtr new_polyg; gaiaGeomCollPtr new_geom; gaiaRingPtr i_ring; gaiaRingPtr o_ring; if (!geom) return NULL; if (geom->DimensionModel == GAIA_XY_Z) new_geom = gaiaAllocGeomCollXYZ (); else if (geom->DimensionModel == GAIA_XY_M) new_geom = gaiaAllocGeomCollXYM (); else if (geom->DimensionModel == GAIA_XY_Z_M) new_geom = gaiaAllocGeomCollXYZM (); else new_geom = gaiaAllocGeomColl (); new_geom->Srid = geom->Srid; new_geom->DeclaredType = geom->DeclaredType; point = geom->FirstPoint; while (point) { /* copying POINTs */ gaiaAddPointToGeomCollXYZM (new_geom, point->X, point->Y, point->Z, point->M); point = point->Next; } line = geom->FirstLinestring; while (line) { /* sanitizing LINESTRINGs */ points = 0; for (iv = 0; iv < line->Points; iv++) { /* PASS I - checking points */ z = 0.0; m = 0.0; if (line->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (line->Coords, iv, &x, &y); } if (iv > 0) { if (last_x == x && last_y == y && last_z == z) ; else points++; } else points++; last_x = x; last_y = y; last_z = z; } if (points < 2) { /* illegal LINESTRING - copying the original one */ new_line = gaiaAddLinestringToGeomColl (new_geom, line->Points); gaiaCopyLinestringCoords (new_line, line); } else { /* valid LINESTRING - sanitizing */ new_line = gaiaAddLinestringToGeomColl (new_geom, points); points = 0; for (iv = 0; iv < line->Points; iv++) { /* PASS II - inserting points */ z = 0.0; m = 0.0; if (line->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (line->Coords, iv, &x, &y); } if (iv > 0) { if (last_x == x && last_y == y && last_z == z) ; else { if (new_line->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (new_line->Coords, points, x, y, z); } else if (new_line->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (new_line->Coords, points, x, y, m); } else if (new_line->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (new_line->Coords, points, x, y, z, m); } else { gaiaSetPoint (new_line->Coords, points, x, y); } points++; } } else { if (new_line->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (new_line->Coords, points, x, y, z); } else if (new_line->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (new_line->Coords, points, x, y, m); } else if (new_line->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (new_line->Coords, points, x, y, z, m); } else { gaiaSetPoint (new_line->Coords, points, x, y); } points++; } last_x = x; last_y = y; last_z = z; } } line = line->Next; } polyg = geom->FirstPolygon; while (polyg) { /* copying POLYGONs */ i_ring = polyg->Exterior; /* sanitizing EXTERIOR RING */ points = 0; for (iv = 0; iv < i_ring->Points; iv++) { /* PASS I - checking points */ z = 0.0; m = 0.0; if (i_ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z); } else if (i_ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m); } else if (i_ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (i_ring->Coords, iv, &x, &y); } if (iv > 0) { if (last_x == x && last_y == y && last_z == z) ; else points++; } else points++; last_x = x; last_y = y; last_z = z; } if (last_x == x && last_y == y && last_z == z) ; else { /* forcing RING closure */ points++; } if (points < 4) { /* illegal RING - copying the original one */ new_polyg = gaiaAddPolygonToGeomColl (new_geom, i_ring->Points, polyg->NumInteriors); o_ring = new_polyg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); } else { /* valid RING - sanitizing */ new_polyg = gaiaAddPolygonToGeomColl (new_geom, points, polyg->NumInteriors); o_ring = new_polyg->Exterior; points = 0; for (iv = 0; iv < i_ring->Points; iv++) { /* PASS II - inserting points */ z = 0.0; m = 0.0; if (i_ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z); } else if (i_ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m); } else if (i_ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (i_ring->Coords, iv, &x, &y); } if (iv > 0) { if (last_x == x && last_y == y && last_z == z) ; else { if (o_ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (o_ring->Coords, points, x, y, z); } else if (o_ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (o_ring->Coords, points, x, y, m); } else if (o_ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (o_ring->Coords, points, x, y, z, m); } else { gaiaSetPoint (o_ring->Coords, points, x, y); } points++; } } else { if (o_ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (o_ring->Coords, points, x, y, z); } else if (o_ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (o_ring->Coords, points, x, y, m); } else if (o_ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (o_ring->Coords, points, x, y, z, m); } else { gaiaSetPoint (o_ring->Coords, points, x, y); } points++; } last_x = x; last_y = y; last_z = z; } } /* PASS III - forcing RING closure */ z = 0.0; m = 0.0; if (i_ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (i_ring->Coords, 0, &x, &y, &z); } else if (i_ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (i_ring->Coords, 0, &x, &y, &m); } else if (i_ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (i_ring->Coords, 0, &x, &y, &z, &m); } else { gaiaGetPoint (i_ring->Coords, 0, &x, &y); } points = o_ring->Points - 1; if (o_ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (o_ring->Coords, points, x, y, z); } else if (o_ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (o_ring->Coords, points, x, y, m); } else if (o_ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (o_ring->Coords, points, x, y, z, m); } else { gaiaSetPoint (o_ring->Coords, points, x, y); } for (ib = 0; ib < new_polyg->NumInteriors; ib++) { /* copying each INTERIOR RING [if any] */ i_ring = polyg->Interiors + ib; /* sanitizing an INTERIOR RING */ points = 0; for (iv = 0; iv < i_ring->Points; iv++) { /* PASS I - checking points */ z = 0.0; m = 0.0; if (i_ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z); } else if (i_ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m); } else if (i_ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (i_ring->Coords, iv, &x, &y); } if (iv > 0) { if (last_x == x && last_y == y && last_z == z) ; else points++; } else points++; last_x = x; last_y = y; last_z = z; } if (last_x == x && last_y == y && last_z == z) ; else { /* forcing RING closure */ points++; } if (points < 4) { /* illegal RING - copying the original one */ o_ring = gaiaAddInteriorRing (new_polyg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } else { /* valid RING - sanitizing */ o_ring = gaiaAddInteriorRing (new_polyg, ib, points); points = 0; for (iv = 0; iv < i_ring->Points; iv++) { /* PASS II - inserting points */ z = 0.0; m = 0.0; if (i_ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (i_ring->Coords, iv, &x, &y, &z); } else if (i_ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (i_ring->Coords, iv, &x, &y, &m); } else if (i_ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (i_ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (i_ring->Coords, iv, &x, &y); } if (iv > 0) { if (last_x == x && last_y == y && last_z == z) ; else { if (o_ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (o_ring->Coords, points, x, y, z); } else if (o_ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (o_ring->Coords, points, x, y, m); } else if (o_ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (o_ring->Coords, points, x, y, z, m); } else { gaiaSetPoint (o_ring->Coords, points, x, y); } points++; } } else { if (o_ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (o_ring->Coords, points, x, y, z); } else if (o_ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (o_ring->Coords, points, x, y, m); } else if (o_ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (o_ring->Coords, points, x, y, z, m); } else { gaiaSetPoint (o_ring->Coords, points, x, y); } points++; } last_x = x; last_y = y; last_z = z; } /* PASS III - forcing RING closure */ z = 0.0; m = 0.0; if (i_ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (i_ring->Coords, 0, &x, &y, &z); } else if (i_ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (i_ring->Coords, 0, &x, &y, &m); } else if (i_ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (i_ring->Coords, 0, &x, &y, &z, &m); } else { gaiaGetPoint (i_ring->Coords, 0, &x, &y); } points = o_ring->Points - 1; if (o_ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (o_ring->Coords, points, x, y, z); } else if (o_ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (o_ring->Coords, points, x, y, m); } else if (o_ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (o_ring->Coords, points, x, y, z, m); } else { gaiaSetPoint (o_ring->Coords, points, x, y); } } } polyg = polyg->Next; } return new_geom; }
GAIAGEO_DECLARE void gaiaRotateCoords (gaiaGeomCollPtr geom, double angle) { /* returns a geometry that is the old geometry with required rotation applied to coordinates */ int ib; int iv; double x; double y; double z; double m; double nx; double ny; double rad = angle * 0.0174532925199432958; double cosine = cos (rad); double sine = sin (rad); gaiaPointPtr point; gaiaPolygonPtr polyg; gaiaLinestringPtr line; gaiaRingPtr ring; if (!geom) return; point = geom->FirstPoint; while (point) { /* shifting POINTs */ x = point->X; y = point->Y; point->X = (x * cosine) + (y * sine); point->Y = (y * cosine) - (x * sine); point = point->Next; } line = geom->FirstLinestring; while (line) { /* rotating LINESTRINGs */ for (iv = 0; iv < line->Points; iv++) { if (line->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (line->Coords, iv, &x, &y, &z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (line->Coords, iv, &x, &y, &m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (line->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (line->Coords, iv, &x, &y); } nx = (x * cosine) + (y * sine); ny = (y * cosine) - (x * sine); if (line->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (line->Coords, iv, nx, ny, z); } else if (line->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (line->Coords, iv, nx, ny, m); } else if (line->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (line->Coords, iv, nx, ny, z, m); } else { gaiaSetPoint (line->Coords, iv, nx, ny); } } line = line->Next; } polyg = geom->FirstPolygon; while (polyg) { /* rotating POLYGONs */ ring = polyg->Exterior; for (iv = 0; iv < ring->Points; iv++) { /* rotating the EXTERIOR RING */ if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } nx = (x * cosine) + (y * sine); ny = (y * cosine) - (x * sine); if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, nx, ny, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, nx, ny, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, nx, ny, z, m); } else { gaiaSetPoint (ring->Coords, iv, nx, ny); } } for (ib = 0; ib < polyg->NumInteriors; ib++) { /* rotating the INTERIOR RINGs */ ring = polyg->Interiors + ib; for (iv = 0; iv < ring->Points; iv++) { if (ring->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ring->Coords, iv, &x, &y, &z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ring->Coords, iv, &x, &y, &m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ring->Coords, iv, &x, &y, &z, &m); } else { gaiaGetPoint (ring->Coords, iv, &x, &y); } nx = (x * cosine) + (y * sine); ny = (y * cosine) - (x * sine); if (ring->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (ring->Coords, iv, nx, ny, z); } else if (ring->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (ring->Coords, iv, nx, ny, m); } else if (ring->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (ring->Coords, iv, nx, ny, z, m); } else { gaiaSetPoint (ring->Coords, iv, nx, ny); } } } polyg = polyg->Next; } gaiaMbrGeometry (geom); }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaExtractLinestringsFromGeomColl (gaiaGeomCollPtr geom) { /* extracts any LINESTRING from a GeometryCollection */ gaiaGeomCollPtr result; gaiaLinestringPtr ln; gaiaLinestringPtr new_ln; int lns = 0; int iv; double x; double y; double z; double m; if (!geom) return NULL; ln = geom->FirstLinestring; while (ln) { lns++; ln = ln->Next; } if (!lns) return NULL; if (geom->DimensionModel == GAIA_XY_Z_M) result = gaiaAllocGeomCollXYZM (); else if (geom->DimensionModel == GAIA_XY_Z) result = gaiaAllocGeomCollXYZ (); else if (geom->DimensionModel == GAIA_XY_M) result = gaiaAllocGeomCollXYM (); else result = gaiaAllocGeomColl (); ln = geom->FirstLinestring; while (ln) { new_ln = gaiaAddLinestringToGeomColl (result, ln->Points); for (iv = 0; iv < ln->Points; iv++) { if (ln->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m); gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m); } else if (ln->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z); gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z); } else if (ln->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m); gaiaSetPointXYM (new_ln->Coords, iv, x, y, m); } else { gaiaGetPoint (ln->Coords, iv, &x, &y); gaiaSetPoint (new_ln->Coords, iv, x, y); } } ln = ln->Next; } result->Srid = geom->Srid; result->DeclaredType = GAIA_MULTILINESTRING; return result; }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaExtractPolygonsFromGeomColl (gaiaGeomCollPtr geom) { /* extracts any POLYGON from a GeometryCollection */ gaiaGeomCollPtr result; gaiaPolygonPtr pg; gaiaPolygonPtr new_pg; gaiaRingPtr rng; gaiaRingPtr new_rng; int pgs = 0; int iv; int ib; double x; double y; double z; double m; if (!geom) return NULL; pg = geom->FirstPolygon; while (pg) { pgs++; pg = pg->Next; } if (!pgs) return NULL; if (geom->DimensionModel == GAIA_XY_Z_M) result = gaiaAllocGeomCollXYZM (); else if (geom->DimensionModel == GAIA_XY_Z) result = gaiaAllocGeomCollXYZ (); else if (geom->DimensionModel == GAIA_XY_M) result = gaiaAllocGeomCollXYM (); else result = gaiaAllocGeomColl (); pg = geom->FirstPolygon; while (pg) { rng = pg->Exterior; new_pg = gaiaAddPolygonToGeomColl (result, rng->Points, pg->NumInteriors); new_rng = new_pg->Exterior; for (iv = 0; iv < rng->Points; iv++) { if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); gaiaSetPointXYZM (new_rng->Coords, iv, x, y, z, m); } else if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); gaiaSetPointXYZ (new_rng->Coords, iv, x, y, z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); gaiaSetPointXYM (new_rng->Coords, iv, x, y, m); } else { gaiaGetPoint (rng->Coords, iv, &x, &y); gaiaSetPoint (new_rng->Coords, iv, x, y); } } for (ib = 0; ib < pg->NumInteriors; ib++) { rng = pg->Interiors + ib; new_rng = gaiaAddInteriorRing (new_pg, ib, rng->Points); for (iv = 0; iv < rng->Points; iv++) { if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); gaiaSetPointXYZM (new_rng->Coords, iv, x, y, z, m); } else if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); gaiaSetPointXYZ (new_rng->Coords, iv, x, y, z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); gaiaSetPointXYM (new_rng->Coords, iv, x, y, m); } else { gaiaGetPoint (rng->Coords, iv, &x, &y); gaiaSetPoint (new_rng->Coords, iv, x, y); } } } pg = pg->Next; } result->Srid = geom->Srid; result->DeclaredType = GAIA_MULTIPOLYGON; return result; }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaDissolveSegments (gaiaGeomCollPtr geom) { /* attempts to dissolve a Geometry into segments */ gaiaGeomCollPtr result; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaLinestringPtr segment; gaiaPolygonPtr pg; gaiaRingPtr rng; int iv; int ib; double x; double y; double z; double m; double x0; double y0; double z0; double m0; if (!geom) return NULL; if (geom->DimensionModel == GAIA_XY_Z_M) result = gaiaAllocGeomCollXYZM (); else if (geom->DimensionModel == GAIA_XY_Z) result = gaiaAllocGeomCollXYZ (); else if (geom->DimensionModel == GAIA_XY_M) result = gaiaAllocGeomCollXYM (); else result = gaiaAllocGeomColl (); pt = geom->FirstPoint; while (pt) { if (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, pt->X, pt->Y, pt->Z, pt->M); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, pt->X, pt->Y, pt->Z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, pt->X, pt->Y, pt->M); else gaiaAddPointToGeomColl (result, pt->X, pt->Y); pt = pt->Next; } ln = geom->FirstLinestring; while (ln) { for (iv = 0; iv < ln->Points; iv++) { if (ln->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m); } else if (ln->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z); } else if (ln->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m); } else { gaiaGetPoint (ln->Coords, iv, &x, &y); } if (iv > 0) { if (geom->DimensionModel == GAIA_XY_Z_M) { if (x != x0 || y != y0 || z != z0 || m != m0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYZM (segment->Coords, 0, x0, y0, z0, m0); gaiaSetPointXYZM (segment->Coords, 1, x, y, z, m); } } else if (geom->DimensionModel == GAIA_XY_Z) { if (x != x0 || y != y0 || z != z0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYZ (segment->Coords, 0, x0, y0, z0); gaiaSetPointXYZ (segment->Coords, 1, x, y, z); } } else if (geom->DimensionModel == GAIA_XY_M) { if (x != x0 || y != y0 || m != m0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYM (segment->Coords, 0, x0, y0, m0); gaiaSetPointXYM (segment->Coords, 1, x, y, m); } } else { if (x != x0 || y != y0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPoint (segment->Coords, 0, x0, y0); gaiaSetPoint (segment->Coords, 1, x, y); } } } x0 = x; y0 = y; z0 = z; m0 = m; } ln = ln->Next; } pg = geom->FirstPolygon; while (pg) { rng = pg->Exterior; for (iv = 0; iv < rng->Points; iv++) { /* exterior Ring */ if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); } else if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); } else { gaiaGetPoint (rng->Coords, iv, &x, &y); } if (iv > 0) { if (geom->DimensionModel == GAIA_XY_Z_M) { if (x != x0 || y != y0 || z != z0 || m != m0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYZM (segment->Coords, 0, x0, y0, z0, m0); gaiaSetPointXYZM (segment->Coords, 1, x, y, z, m); } } else if (geom->DimensionModel == GAIA_XY_Z) { if (x != x0 || y != y0 || z != z0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYZ (segment->Coords, 0, x0, y0, z0); gaiaSetPointXYZ (segment->Coords, 1, x, y, z); } } else if (geom->DimensionModel == GAIA_XY_M) { if (x != x0 || y != y0 || m != m0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYM (segment->Coords, 0, x0, y0, m0); gaiaSetPointXYM (segment->Coords, 1, x, y, m); } } else { if (x != x0 || y != y0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPoint (segment->Coords, 0, x0, y0); gaiaSetPoint (segment->Coords, 1, x, y); } } } x0 = x; y0 = y; z0 = z; m0 = m; } for (ib = 0; ib < pg->NumInteriors; ib++) { rng = pg->Interiors + ib; for (iv = 0; iv < rng->Points; iv++) { /* interior Ring */ if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); } else if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); } else { gaiaGetPoint (rng->Coords, iv, &x, &y); } if (iv > 0) { if (geom->DimensionModel == GAIA_XY_Z_M) { if (x != x0 || y != y0 || z != z0 || m != m0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYZM (segment->Coords, 0, x0, y0, z0, m0); gaiaSetPointXYZM (segment->Coords, 1, x, y, z, m); } } else if (geom->DimensionModel == GAIA_XY_Z) { if (x != x0 || y != y0 || z != z0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYZ (segment->Coords, 0, x0, y0, z0); gaiaSetPointXYZ (segment->Coords, 1, x, y, z); } } else if (geom->DimensionModel == GAIA_XY_M) { if (x != x0 || y != y0 || m != m0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPointXYM (segment->Coords, 0, x0, y0, m0); gaiaSetPointXYM (segment->Coords, 1, x, y, m); } } else { if (x != x0 || y != y0) { segment = gaiaAddLinestringToGeomColl (result, 2); gaiaSetPoint (segment->Coords, 0, x0, y0); gaiaSetPoint (segment->Coords, 1, x, y); } } } x0 = x; y0 = y; z0 = z; m0 = m; } } pg = pg->Next; } result->Srid = geom->Srid; return result; }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaLinearize (gaiaGeomCollPtr geom, int force_multi) { /* attempts to rearrange a generic Geometry into a (multi)linestring */ int pts = 0; int lns = 0; gaiaGeomCollPtr result; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaLinestringPtr new_ln; gaiaPolygonPtr pg; gaiaRingPtr rng; int iv; int ib; double x; double y; double m; double z; if (!geom) return NULL; pt = geom->FirstPoint; while (pt) { pts++; pt = pt->Next; } ln = geom->FirstLinestring; while (ln) { lns++; ln = ln->Next; } if (pts || lns) return NULL; if (geom->DimensionModel == GAIA_XY_Z_M) result = gaiaAllocGeomCollXYZM (); else if (geom->DimensionModel == GAIA_XY_Z) result = gaiaAllocGeomCollXYZ (); else if (geom->DimensionModel == GAIA_XY_M) result = gaiaAllocGeomCollXYM (); else result = gaiaAllocGeomColl (); result->Srid = geom->Srid; if (force_multi) result->DeclaredType = GAIA_MULTILINESTRING; pg = geom->FirstPolygon; while (pg) { /* dissolving any POLYGON as simple LINESTRINGs (rings) */ rng = pg->Exterior; new_ln = gaiaAddLinestringToGeomColl (result, rng->Points); for (iv = 0; iv < rng->Points; iv++) { /* copying the EXTERIOR RING as LINESTRING */ if (geom->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m); } else if (geom->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z); } else if (geom->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); gaiaSetPointXYM (new_ln->Coords, iv, x, y, m); } else { gaiaGetPoint (rng->Coords, iv, &x, &y); gaiaSetPoint (new_ln->Coords, iv, x, y); } } for (ib = 0; ib < pg->NumInteriors; ib++) { rng = pg->Interiors + ib; new_ln = gaiaAddLinestringToGeomColl (result, rng->Points); for (iv = 0; iv < rng->Points; iv++) { /* copying an INTERIOR RING as LINESTRING */ if (geom->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, iv, &x, &y, &z, &m); gaiaSetPointXYZM (new_ln->Coords, iv, x, y, z, m); } else if (geom->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, iv, &x, &y, &z); gaiaSetPointXYZ (new_ln->Coords, iv, x, y, z); } else if (geom->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, iv, &x, &y, &m); gaiaSetPointXYM (new_ln->Coords, iv, x, y, m); } else { gaiaGetPoint (rng->Coords, iv, &x, &y); gaiaSetPoint (new_ln->Coords, iv, x, y); } } } pg = pg->Next; } if (result->FirstLinestring == NULL) { gaiaFreeGeomColl (result); return NULL; } return result; }
static void auxGridSnapPolygon (gaiaPolygonPtr pg, gaiaGeomCollPtr result, double origin_x, double origin_y, double origin_z, double origin_m, double size_x, double size_y, double size_z, double size_m) { /* snapping a Polygon to a regular Grid */ int ib; int holes = 0; int count; int next_hole = 0; int iv; gaiaRingPtr rng; gaiaPolygonPtr pgx; gaiaPointPtr pt; gaiaDynamicLinePtr rng_ext; gaiaDynamicLinePtr dyn; gaiaDynamicLinePtr *rng_ints = NULL; if (pg == NULL || result == NULL) return; /* snapping the Exterior Ring */ rng = pg->Exterior; rng_ext = auxGridSnapRing (rng, origin_x, origin_y, origin_z, origin_m, size_x, size_y, size_z, size_m); if (rng_ext == NULL) /* skipping any collaped Polygon */ return; if (pg->NumInteriors) { /* snapping any Interior Ring */ rng_ints = malloc (sizeof (gaiaRingPtr *) * pg->NumInteriors); for (ib = 0; ib < pg->NumInteriors; ib++) { rng = pg->Interiors + ib; *(rng_ints + ib) = auxGridSnapRing (rng, origin_x, origin_y, origin_z, origin_m, size_x, size_y, size_z, size_m); if (*(rng_ints + ib) != NULL) holes++; } } /* inserting into the result Geometry */ pt = rng_ext->First; count = 0; while (pt) { /* counting how many points are in the Exterior Ring */ count++; pt = pt->Next; } pgx = gaiaAddPolygonToGeomColl (result, count, holes); rng = pgx->Exterior; iv = 0; pt = rng_ext->First; while (pt) { /* copying Exterior Ring points */ if (rng->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, pt->X, pt->Y, pt->Z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, pt->X, pt->Y, pt->M); } else if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, pt->X, pt->Y, pt->Z, pt->M); } else { gaiaSetPoint (rng->Coords, iv, pt->X, pt->Y); } iv++; pt = pt->Next; } if (holes > 0) { /* setting up any not-collapsed Hole */ for (ib = 0; ib < pg->NumInteriors; ib++) { if (*(rng_ints + ib) == NULL) continue; dyn = *(rng_ints + ib); pt = dyn->First; count = 0; while (pt) { /* counting how many points are in the Exterior Ring */ count++; pt = pt->Next; } rng = gaiaAddInteriorRing (pgx, next_hole++, count); iv = 0; pt = dyn->First; while (pt) { /* copying Interior Ring points */ if (rng->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, pt->X, pt->Y, pt->Z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, pt->X, pt->Y, pt->M); } else if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, pt->X, pt->Y, pt->Z, pt->M); } else { gaiaSetPoint (rng->Coords, iv, pt->X, pt->Y); } iv++; pt = pt->Next; } } } /* memory clean-up */ gaiaFreeDynamicLine (rng_ext); if (rng_ints) { for (ib = 0; ib < pg->NumInteriors; ib++) { dyn = *(rng_ints + ib); if (dyn) gaiaFreeDynamicLine (dyn); } free (rng_ints); } }
static void auxGridSnapLinestring (gaiaLinestringPtr ln, gaiaGeomCollPtr result, double origin_x, double origin_y, double origin_z, double origin_m, double size_x, double size_y, double size_z, double size_m) { /* snapping a Linestring to a regular Grid */ double x; double y; double z; double m; int has_z = 0; int has_m = 0; int iv; gaiaDynamicLinePtr dyn; gaiaPointPtr pt; gaiaLinestringPtr lnx; int count = 0; if (ln == NULL || result == NULL) return; if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) has_z = 1; if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) has_m = 1; dyn = gaiaAllocDynamicLine (); for (iv = 0; iv < ln->Points; iv++) { /* snapping each Vertex to the given grid */ int to_be_inserted = 0; z = 0.0; m = 0.0; if (has_z && has_m) { gaiaGetPointXYZM (ln->Coords, iv, &x, &y, &z, &m); } else if (has_z) { gaiaGetPointXYZ (ln->Coords, iv, &x, &y, &z); } else if (has_m) { gaiaGetPointXYM (ln->Coords, iv, &x, &y, &m); } else { gaiaGetPoint (ln->Coords, iv, &x, &y); } /* snapping coords to the given grid */ if (size_x > 0.0) x = rint ((x - origin_x) / size_x) * size_x + origin_x; if (size_y > 0.0) y = rint ((y - origin_y) / size_y) * size_y + origin_y; if (has_z && size_z > 0.0) z = rint ((z - origin_z) / size_z) * size_z + origin_z; if (has_m && size_m > 0.0) m = rint ((m - origin_m) / size_m) * size_m + origin_m; if (dyn->Last == NULL) to_be_inserted = 1; else { /* skipping repeated points */ pt = dyn->Last; if (has_z && has_m) { if (pt->X == x && pt->Y == y && pt->Z == z && pt->M == m) ; else to_be_inserted = 1; } else if (has_z) { if (pt->X == x && pt->Y == y && pt->Z == z) ; else to_be_inserted = 1; } else if (has_m) { if (pt->X == x && pt->Y == y && pt->M == m) ; else to_be_inserted = 1; } else { if (pt->X == x && pt->Y == y) ; else to_be_inserted = 1; } } if (to_be_inserted) { if (has_z && has_m) gaiaAppendPointZMToDynamicLine (dyn, x, y, z, m); else if (has_z) gaiaAppendPointZToDynamicLine (dyn, x, y, z); else if (has_m) gaiaAppendPointMToDynamicLine (dyn, x, y, m); else gaiaAppendPointToDynamicLine (dyn, x, y); } } /* checking for validity */ pt = dyn->First; while (pt) { /* counting how many points are there */ count++; pt = pt->Next; } if (count < 2) { /* skipping any collapsed line */ gaiaFreeDynamicLine (dyn); return; } /* inserting into the result Geometry */ lnx = gaiaAddLinestringToGeomColl (result, count); iv = 0; pt = dyn->First; while (pt) { /* copying points */ if (lnx->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (lnx->Coords, iv, pt->X, pt->Y, pt->Z); } else if (lnx->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (lnx->Coords, iv, pt->X, pt->Y, pt->M); } else if (lnx->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (lnx->Coords, iv, pt->X, pt->Y, pt->Z, pt->M); } else { gaiaSetPoint (lnx->Coords, iv, pt->X, pt->Y); } iv++; pt = pt->Next; } gaiaFreeDynamicLine (dyn); }
static gaiaGeomCollPtr fromGeosGeometry (const GEOSGeometry * geos, const int dimension_model) { /* converting a GEOS Geometry into a GAIA Geometry */ int type; int itemType; unsigned int dims; int iv; int ib; int it; int sub_it; int nItems; int nSubItems; int holes; unsigned int points; double x; double y; double z; const GEOSCoordSequence *cs; const GEOSGeometry *geos_ring; const GEOSGeometry *geos_item; const GEOSGeometry *geos_sub_item; gaiaGeomCollPtr gaia = NULL; gaiaLinestringPtr ln; gaiaPolygonPtr pg; gaiaRingPtr rng; if (!geos) return NULL; type = GEOSGeomTypeId (geos); switch (type) { case GEOS_POINT: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_POINT; gaia->Srid = GEOSGetSRID (geos); cs = GEOSGeom_getCoordSeq (geos); GEOSCoordSeq_getDimensions (cs, &dims); if (dims == 3) { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); GEOSCoordSeq_getZ (cs, 0, &z); } else { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (gaia, x, y, z); else if (dimension_model == GAIA_XY_M) gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0); else if (dimension_model == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0); else gaiaAddPointToGeomColl (gaia, x, y); break; case GEOS_LINESTRING: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_LINESTRING; gaia->Srid = GEOSGetSRID (geos); cs = GEOSGeom_getCoordSeq (geos); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } break; case GEOS_POLYGON: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); gaia->DeclaredType = GAIA_POLYGON; gaia->Srid = GEOSGetSRID (geos); /* exterior ring */ holes = GEOSGetNumInteriorRings (geos); geos_ring = GEOSGetExteriorRing (geos); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); pg = gaiaAddPolygonToGeomColl (gaia, points, holes); rng = pg->Exterior; for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } for (ib = 0; ib < holes; ib++) { /* interior rings */ geos_ring = GEOSGetInteriorRingN (geos, ib); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); rng = gaiaAddInteriorRing (pg, ib, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } } break; case GEOS_MULTIPOINT: case GEOS_MULTILINESTRING: case GEOS_MULTIPOLYGON: case GEOS_GEOMETRYCOLLECTION: if (dimension_model == GAIA_XY_Z) gaia = gaiaAllocGeomCollXYZ (); else if (dimension_model == GAIA_XY_M) gaia = gaiaAllocGeomCollXYM (); else if (dimension_model == GAIA_XY_Z_M) gaia = gaiaAllocGeomCollXYZM (); else gaia = gaiaAllocGeomColl (); if (type == GEOS_MULTIPOINT) gaia->DeclaredType = GAIA_MULTIPOINT; else if (type == GEOS_MULTILINESTRING) gaia->DeclaredType = GAIA_MULTILINESTRING; else if (type == GEOS_MULTIPOLYGON) gaia->DeclaredType = GAIA_MULTIPOLYGON; else gaia->DeclaredType = GAIA_GEOMETRYCOLLECTION; gaia->Srid = GEOSGetSRID (geos); nItems = GEOSGetNumGeometries (geos); for (it = 0; it < nItems; it++) { /* looping on elementaty geometries */ geos_item = GEOSGetGeometryN (geos, it); itemType = GEOSGeomTypeId (geos_item); switch (itemType) { case GEOS_POINT: cs = GEOSGeom_getCoordSeq (geos_item); GEOSCoordSeq_getDimensions (cs, &dims); if (dims == 3) { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); GEOSCoordSeq_getZ (cs, 0, &z); } else { GEOSCoordSeq_getX (cs, 0, &x); GEOSCoordSeq_getY (cs, 0, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (gaia, x, y, z); else if (dimension_model == GAIA_XY_M) gaiaAddPointToGeomCollXYM (gaia, x, y, 0.0); else if (dimension_model == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (gaia, x, y, z, 0.0); else gaiaAddPointToGeomColl (gaia, x, y); break; case GEOS_LINESTRING: cs = GEOSGeom_getCoordSeq (geos_item); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } break; case GEOS_MULTILINESTRING: nSubItems = GEOSGetNumGeometries (geos_item); for (sub_it = 0; sub_it < nSubItems; sub_it++) { /* looping on elementaty geometries */ geos_sub_item = GEOSGetGeometryN (geos_item, sub_it); cs = GEOSGeom_getCoordSeq (geos_sub_item); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); ln = gaiaAddLinestringToGeomColl (gaia, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (ln->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (ln->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (ln->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (ln->Coords, iv, x, y); } } } break; case GEOS_POLYGON: /* exterior ring */ holes = GEOSGetNumInteriorRings (geos_item); geos_ring = GEOSGetExteriorRing (geos_item); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); pg = gaiaAddPolygonToGeomColl (gaia, points, holes); rng = pg->Exterior; for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } for (ib = 0; ib < holes; ib++) { /* interior rings */ geos_ring = GEOSGetInteriorRingN (geos_item, ib); cs = GEOSGeom_getCoordSeq (geos_ring); GEOSCoordSeq_getDimensions (cs, &dims); GEOSCoordSeq_getSize (cs, &points); rng = gaiaAddInteriorRing (pg, ib, points); for (iv = 0; iv < (int) points; iv++) { if (dims == 3) { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); GEOSCoordSeq_getZ (cs, iv, &z); } else { GEOSCoordSeq_getX (cs, iv, &x); GEOSCoordSeq_getY (cs, iv, &y); z = 0.0; } if (dimension_model == GAIA_XY_Z) { gaiaSetPointXYZ (rng->Coords, iv, x, y, z); } else if (dimension_model == GAIA_XY_M) { gaiaSetPointXYM (rng->Coords, iv, x, y, 0.0); } else if (dimension_model == GAIA_XY_Z_M) { gaiaSetPointXYZM (rng->Coords, iv, x, y, z, 0.0); } else { gaiaSetPoint (rng->Coords, iv, x, y); } } } break; }; } break; }; return gaia; }