/* * Creates a 3D (xyz) multipoint object in SpatiaLite * * first is a gaiaPointPtr to the first point in a linked list of points. * All of the points given to the function are 3D (xyz) points. There will be at least 1 point in the list. * * Returns a geometry collection containing the created multipoint object. */ static gaiaGeomCollPtr geoJSON_multipoint_xyz (struct geoJson_data *p_data, gaiaPointPtr first) { gaiaPointPtr p = first; gaiaPointPtr p_n; gaiaGeomCollPtr geom = NULL; /* If no pointers are given, return. */ if (first == NULL) return NULL; /* Creates and allocates a geometry collection containing a multipoint. */ geom = gaiaAllocGeomCollXYZ (); if (geom == NULL) return NULL; geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom); geom->DeclaredType = GAIA_MULTIPOINT; /* For every 3D (xyz) point, add it to the geometry collection. */ while (p != NULL) { gaiaAddPointToGeomCollXYZ (geom, p->X, p->Y, p->Z); p_n = p->Next; geoJsonMapDynClean (p_data, p); gaiaFreePoint (p); p = p_n; } return geom; }
static gaiaGeomCollPtr gaiaGeoJsonGeometryFromPointZ (struct geoJson_data *p_data, gaiaPointPtr point, int srid) { /* builds a GEOMETRY containing a POINTZ */ gaiaGeomCollPtr geom = NULL; geom = gaiaAllocGeomCollXYZ (); geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom); geom->DeclaredType = GAIA_POINTZ; geom->Srid = srid; gaiaAddPointToGeomCollXYZ (geom, point->X, point->Y, point->Z); geoJsonMapDynClean (p_data, point); gaiaFreePoint (point); return geom; }
GAIAGEO_DECLARE gaiaGeomCollPtr gaiaExtractPointsFromGeomColl (gaiaGeomCollPtr geom) { /* extracts any POINT from a GeometryCollection */ gaiaGeomCollPtr result; gaiaPointPtr pt; int pts = 0; if (!geom) return NULL; pt = geom->FirstPoint; while (pt) { pts++; pt = pt->Next; } if (!pts) 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; } result->Srid = geom->Srid; result->DeclaredType = GAIA_MULTIPOINT; return result; }
static int kml_parse_point (struct kml_data *p_data, gaiaGeomCollPtr geom, kmlNodePtr node, kmlNodePtr * next) { /* parsing a <Point> */ double x; double y; double z; int has_z; gaiaGeomCollPtr pt; gaiaGeomCollPtr last; if (strcmp (node->Tag, "coordinates") == 0) { /* parsing a KML <Point> */ if (!kml_parse_point_v2 (node->Coordinates, &x, &y, &z, &has_z)) return 0; node = node->Next; if (node == NULL) return 0; if (strcmp (node->Tag, "coordinates") == 0) ; else return 0; node = node->Next; if (node == NULL) return 0; if (strcmp (node->Tag, "Point") == 0) ; else return 0; *next = node->Next; goto ok; } return 0; ok: /* ok, KML nodes match as expected */ if (has_z) { pt = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pt); gaiaAddPointToGeomCollXYZ (pt, x, y, z); } else { pt = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pt); gaiaAddPointToGeomColl (pt, x, y); } last = geom; while (1) { /* searching the last Geometry within chain */ if (last->Next == NULL) break; last = last->Next; } last->Next = pt; return 1; }
static gaiaGeomCollPtr kml_validate_geometry (struct kml_data *p_data, gaiaGeomCollPtr chain) { int xy = 0; int xyz = 0; int pts = 0; int lns = 0; int pgs = 0; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaPolygonPtr pg; gaiaPointPtr save_pt = NULL; gaiaLinestringPtr save_ln = NULL; gaiaPolygonPtr save_pg = NULL; gaiaRingPtr i_ring; gaiaRingPtr o_ring; int ib; gaiaGeomCollPtr g; gaiaGeomCollPtr geom; g = chain; while (g) { if (g != chain) { if (g->DimensionModel == GAIA_XY) xy++; if (g->DimensionModel == GAIA_XY_Z) xyz++; } pt = g->FirstPoint; while (pt) { pts++; save_pt = pt; pt = pt->Next; } ln = g->FirstLinestring; while (ln) { lns++; save_ln = ln; ln = ln->Next; } pg = g->FirstPolygon; while (pg) { pgs++; save_pg = pg; pg = pg->Next; } g = g->Next; } if (pts == 1 && lns == 0 && pgs == 0) { /* POINT */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION) geom->DeclaredType = GAIA_MULTIPOINT; else geom->DeclaredType = GAIA_POINT; gaiaAddPointToGeomColl (geom, save_pt->X, save_pt->Y); return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION) geom->DeclaredType = GAIA_MULTIPOINT; else geom->DeclaredType = GAIA_POINT; gaiaAddPointToGeomCollXYZ (geom, save_pt->X, save_pt->Y, save_pt->Z); return geom; } } if (pts == 0 && lns == 1 && pgs == 0) { /* LINESTRING */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); } if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION) geom->DeclaredType = GAIA_MULTILINESTRING; else geom->DeclaredType = GAIA_LINESTRING; ln = gaiaAddLinestringToGeomColl (geom, save_ln->Points); gaiaCopyLinestringCoords (ln, save_ln); return geom; } if (pts == 0 && lns == 0 && pgs == 1) { /* POLYGON */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); } if (chain->DeclaredType == GAIA_GEOMETRYCOLLECTION) geom->DeclaredType = GAIA_MULTIPOLYGON; else geom->DeclaredType = GAIA_POLYGON; i_ring = save_pg->Exterior; pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, save_pg->NumInteriors); o_ring = pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < save_pg->NumInteriors; ib++) { i_ring = save_pg->Interiors + ib; o_ring = gaiaAddInteriorRing (pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } return geom; } if (pts >= 1 && lns == 0 && pgs == 0) { /* MULTIPOINT */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTIPOINT; g = chain; while (g) { pt = g->FirstPoint; while (pt) { gaiaAddPointToGeomColl (geom, pt->X, pt->Y); pt = pt->Next; } g = g->Next; } return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTIPOINT; g = chain; while (g) { pt = g->FirstPoint; while (pt) { gaiaAddPointToGeomCollXYZ (geom, pt->X, pt->Y, pt->Z); pt = pt->Next; } g = g->Next; } return geom; } } if (pts == 0 && lns >= 1 && pgs == 0) { /* MULTILINESTRING */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTILINESTRING; g = chain; while (g) { ln = g->FirstLinestring; while (ln) { save_ln = gaiaAddLinestringToGeomColl (geom, ln->Points); gaiaCopyLinestringCoords (save_ln, ln); ln = ln->Next; } g = g->Next; } return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTILINESTRING; g = chain; while (g) { ln = g->FirstLinestring; while (ln) { save_ln = gaiaAddLinestringToGeomColl (geom, ln->Points); gaiaCopyLinestringCoords (save_ln, ln); ln = ln->Next; } g = g->Next; } return geom; } } if (pts == 0 && lns == 0 && pgs >= 1) { /* MULTIPOLYGON */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTIPOLYGON; g = chain; while (g) { pg = g->FirstPolygon; while (pg) { i_ring = pg->Exterior; save_pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, pg->NumInteriors); o_ring = save_pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < pg->NumInteriors; ib++) { i_ring = pg->Interiors + ib; o_ring = gaiaAddInteriorRing (save_pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } pg = pg->Next; } g = g->Next; } return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_MULTIPOLYGON; g = chain; while (g) { pg = g->FirstPolygon; while (pg) { i_ring = pg->Exterior; save_pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, pg->NumInteriors); o_ring = save_pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < pg->NumInteriors; ib++) { i_ring = pg->Interiors + ib; o_ring = gaiaAddInteriorRing (save_pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } pg = pg->Next; } g = g->Next; } return geom; } } if ((pts + lns + pgs) > 0) { /* GEOMETRYCOLLECTION */ if (xy > 0) { /* 2D [XY] */ geom = gaiaAllocGeomColl (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_GEOMETRYCOLLECTION; g = chain; while (g) { pt = g->FirstPoint; while (pt) { gaiaAddPointToGeomColl (geom, pt->X, pt->Y); pt = pt->Next; } ln = g->FirstLinestring; while (ln) { save_ln = gaiaAddLinestringToGeomColl (geom, ln->Points); gaiaCopyLinestringCoords (save_ln, ln); ln = ln->Next; } pg = g->FirstPolygon; while (pg) { i_ring = pg->Exterior; save_pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, pg->NumInteriors); o_ring = save_pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < pg->NumInteriors; ib++) { i_ring = pg->Interiors + ib; o_ring = gaiaAddInteriorRing (save_pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } pg = pg->Next; } g = g->Next; } return geom; } else { /* 3D [XYZ] */ geom = gaiaAllocGeomCollXYZ (); kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg); geom->DeclaredType = GAIA_GEOMETRYCOLLECTION; g = chain; while (g) { pt = g->FirstPoint; while (pt) { gaiaAddPointToGeomCollXYZ (geom, pt->X, pt->Y, pt->Z); pt = pt->Next; } ln = g->FirstLinestring; while (ln) { save_ln = gaiaAddLinestringToGeomColl (geom, ln->Points); gaiaCopyLinestringCoords (save_ln, ln); ln = ln->Next; } pg = g->FirstPolygon; while (pg) { i_ring = pg->Exterior; save_pg = gaiaAddPolygonToGeomColl (geom, i_ring->Points, pg->NumInteriors); o_ring = save_pg->Exterior; gaiaCopyRingCoords (o_ring, i_ring); for (ib = 0; ib < pg->NumInteriors; ib++) { i_ring = pg->Interiors + ib; o_ring = gaiaAddInteriorRing (save_pg, ib, i_ring->Points); gaiaCopyRingCoords (o_ring, i_ring); } pg = pg->Next; } g = g->Next; } return geom; } } return NULL; }
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 gaiaDissolvePoints (gaiaGeomCollPtr geom) { /* attempts to dissolve a Geometry into points */ gaiaGeomCollPtr result; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaPolygonPtr pg; gaiaRingPtr rng; int iv; int ib; double x; double y; double z; double m; 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 (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, x, y, z, m); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, x, y, z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, x, y, m); else gaiaAddPointToGeomColl (result, x, y); } 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 (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, x, y, z, m); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, x, y, z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, x, y, m); else gaiaAddPointToGeomColl (result, x, y); } 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 (geom->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (result, x, y, z, m); else if (geom->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (result, x, y, z); else if (geom->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (result, x, y, m); else gaiaAddPointToGeomColl (result, x, y); } } pg = pg->Next; } result->Srid = geom->Srid; return result; }
static void auxGridSnapPoint (int dimension_model, gaiaPointPtr pt, 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 Point to a regular Grid */ double x = pt->X; double y = pt->Y; double z = 0.0; double m = 0.0; int has_z = 0; int has_m = 0; gaiaPointPtr ptx; if (pt == NULL || result == NULL) return; if (dimension_model == GAIA_XY_Z || dimension_model == GAIA_XY_Z_M) has_z = 1; if (dimension_model == GAIA_XY_M || dimension_model == GAIA_XY_Z_M) has_m = 1; if (has_z) z = pt->Z; if (has_m) m = pt->M; /* 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; ptx = result->FirstPoint; while (ptx) { /* checking if already defined */ if (has_z && has_m) { if (ptx->X == x && ptx->Y == y && ptx->Z == z && ptx->M == m) return; } else if (has_z) { if (ptx->X == x && ptx->Y == y && ptx->Z == z) return; } else if (has_m) { if (ptx->X == x && ptx->Y == y && ptx->M == m) return; } else { if (ptx->X == x && ptx->Y == y) return; } ptx = ptx->Next; } /* inserting the snapped Point into the result Geometry */ if (has_z && has_m) gaiaAddPointToGeomCollXYZM (result, x, y, z, m); else if (has_z) gaiaAddPointToGeomCollXYZ (result, x, y, z); else if (has_m) gaiaAddPointToGeomCollXYM (result, x, y, m); else gaiaAddPointToGeomColl (result, x, y); }
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; }