Example #1
0
/* 
 * Creates a 2D (xy) 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 2D (xy) points. There will be at least 1 point in the list.
 *
 * Returns a geometry collection containing the created multipoint object.
 */
static gaiaGeomCollPtr
geoJSON_multipoint_xy (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 = gaiaAllocGeomColl ();
    if (geom == NULL)
	return NULL;
    geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
    geom->DeclaredType = GAIA_MULTIPOINT;

    /* For every 2D (xy) point, add it to the geometry collection. */
    while (p != NULL)
      {
	  gaiaAddPointToGeomColl (geom, p->X, p->Y);
	  p_n = p->Next;
	  geoJsonMapDynClean (p_data, p);
	  gaiaFreePoint (p);
	  p = p_n;
      }
    return geom;
}
Example #2
0
static gaiaGeomCollPtr
gaiaGeoJsonGeometryFromLinestring (struct geoJson_data *p_data,
				   gaiaLinestringPtr line, int srid)
{
/* builds a GEOMETRY containing a LINESTRING */
    gaiaGeomCollPtr geom = NULL;
    gaiaLinestringPtr line2;
    int iv;
    double x;
    double y;
    geom = gaiaAllocGeomColl ();
    geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
    geom->DeclaredType = GAIA_LINESTRING;
    geom->Srid = srid;
    line2 = gaiaAddLinestringToGeomColl (geom, line->Points);
    for (iv = 0; iv < line2->Points; iv++)
      {
	  /* sets the POINTS for the exterior ring */
	  gaiaGetPoint (line->Coords, iv, &x, &y);
	  gaiaSetPoint (line2->Coords, iv, x, y);
      }
    geoJsonMapDynClean (p_data, line);
    gaiaFreeLinestring (line);
    return geom;
}
static void
add_linestring_to_geometry (struct gml_params *params,
			    gaiaDynamicLinePtr dyn_line)
{
/* adding a LINESTRING to current Geometry */
    int iv = 0;
    gaiaPointPtr pt;
    gaiaLinestringPtr line;

    if (params->geometry == NULL)
	params->geometry = gaiaAllocGeomColl ();

    pt = dyn_line->First;
    while (pt)
      {
	  /* counting how many POINTs are there */
	  iv++;
	  pt = pt->Next;
      }
    line = gaiaAddLinestringToGeomColl (params->geometry, iv);

    iv = 0;
    pt = dyn_line->First;
    while (pt)
      {
	  /* inserting any POINT into LINESTRING */
	  gaiaSetPoint (line->Coords, iv, pt->X, pt->Y);
	  iv++;
	  pt = pt->Next;
      }
    gaiaFreeDynamicLine (dyn_line);
}
Example #4
0
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCriticalPointFromGEOSmsg_r (const void *p_cache)
{
/*
/ Attempts to return a Point Geometry extracted from the latest GEOS 
/ error / warning message
*/
    double x;
    double y;
    gaiaGeomCollPtr geom;
    const char *msg;
    struct splite_internal_cache *cache =
	(struct splite_internal_cache *) p_cache;

    if (cache == NULL)
	return NULL;
    if (cache->magic1 == SPATIALITE_CACHE_MAGIC1
	|| cache->magic2 == SPATIALITE_CACHE_MAGIC2)
	;
    else
	return NULL;

    msg = cache->gaia_geos_error_msg;
    if (msg == NULL)
	msg = cache->gaia_geos_warning_msg;
    if (msg == NULL)
	return NULL;
    if (!check_geos_critical_point (msg, &x, &y))
	return NULL;
    geom = gaiaAllocGeomColl ();
    gaiaAddPointToGeomColl (geom, x, y);
    return geom;
}
Example #5
0
static gaiaGeomCollPtr
kml_build_geometry (struct kml_data *p_data, kmlNodePtr tree)
{
/* attempting to build a geometry from KML nodes */
    gaiaGeomCollPtr geom;
    gaiaGeomCollPtr result;
    int geom_type;
    kmlNodePtr next;

    if (tree == NULL)
	return NULL;
    geom_type = guessKmlGeometryType (tree);
    if (geom_type == GAIA_KML_UNKNOWN)
      {
	  /* unsupported main geometry type */
	  return NULL;
      }
/* creating the main geometry */
    geom = gaiaAllocGeomColl ();

    switch (geom_type)
      {
	  /* parsing KML nodes accordingly with declared KML type */
      case GAIA_KML_POINT:
	  geom->DeclaredType = GAIA_POINT;
	  if (!kml_parse_point (p_data, geom, tree->Next, &next))
	      goto error;
	  break;
      case GAIA_KML_LINESTRING:
	  geom->DeclaredType = GAIA_LINESTRING;
	  if (!kml_parse_linestring (p_data, geom, tree->Next, &next))
	      goto error;
	  break;
      case GAIA_KML_POLYGON:
	  geom->DeclaredType = GAIA_POLYGON;
	  if (!kml_parse_polygon (p_data, geom, tree->Next, &next))
	      goto error;
	  if (next != NULL)
	      goto error;
	  break;
      case GAIA_KML_MULTIGEOMETRY:
	  geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
	  if (!kml_parse_multi_geometry (p_data, geom, tree->Next))
	      goto error;
	  break;
      };

/* attempting to build the final geometry */
    result = kml_validate_geometry (p_data, geom);
    if (result == NULL)
	goto error;
    kml_free_geom_chain (geom);
    return result;

  error:
    kml_free_geom_chain (geom);
    return NULL;
}
Example #6
0
/*
 * See geomColl_xy for description.
 *
 * The only difference between this function and geomColl_xy is that the 'declaredType' field of the structs
 * in the linked list for this function will only contain the following types:
 *
 *	GAIA_POINTZ, GAIA_LINESTRINGZ, GAIA_POLYGONZ,
 * 	GAIA_MULTIPOINTZ, GAIA_MULTILINESTRINGZ, GAIA_MULTIPOLYGONZ
 */
static gaiaGeomCollPtr
geoJSON_geomColl_xyz (struct geoJson_data *p_data, gaiaGeomCollPtr first)
{
    gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
    if (geom == NULL)
	return NULL;
    geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
    geom->DeclaredType = GAIA_GEOMETRYCOLLECTION;
    geom->DimensionModel = GAIA_XY_Z;
    geoJSON_geomColl_common (p_data, first, geom);
    return geom;
}
Example #7
0
static gaiaGeomCollPtr
gaiaGeoJsonGeometryFromPoint (struct geoJson_data *p_data, gaiaPointPtr point,
			      int srid)
{
/* builds a GEOMETRY containing a POINT */
    gaiaGeomCollPtr geom = NULL;
    geom = gaiaAllocGeomColl ();
    geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
    geom->DeclaredType = GAIA_POINT;
    geom->Srid = srid;
    gaiaAddPointToGeomColl (geom, point->X, point->Y);
    geoJsonMapDynClean (p_data, point);
    gaiaFreePoint (point);
    return geom;
}
int main (int argc, char *argv[])
{
#ifndef OMIT_GEOS	/* only if GEOS is supported */
    gaiaGeomCollPtr result;
    void *resultVoid;
    int returnValue = 0;
    
    /* Common setup */
    
    gaiaGeomCollPtr emptyGeometry = gaiaAllocGeomColl();
    
    /* Tests start here */
    
    /* null input test */
    result = gaiaFromGeos_XY ( (const void*) NULL );
    if (result != NULL) {
	fprintf(stderr, "bad result at %s:%i\n", __FILE__, __LINE__);
	returnValue = -1;
	goto exit;
    }
    
    resultVoid = gaiaToGeos ((gaiaGeomCollPtr)NULL);
    if (resultVoid != NULL) {
	fprintf(stderr, "bad result at %s:%i\n", __FILE__, __LINE__);
	returnValue = -2;
	goto exit;
    }
    
    /* unknown type geometry collection */
    resultVoid = gaiaToGeos ( emptyGeometry );
    if (resultVoid != NULL) {
	fprintf(stderr, "bad result at %s:%i\n", __FILE__, __LINE__);
	returnValue = -3;
	goto exit;
    }
    
    /* Cleanup and exit */
exit:
    gaiaFreeGeomColl (emptyGeometry);
    return returnValue;

#endif	/* end GEOS conditional */

    return 0;
}
static void
add_point_to_geometry (struct gml_params *params, gaiaDynamicLinePtr dyn_line)
{
/* adding a POINT to current Geometry */
    gaiaPointPtr pt;

    if (params->geometry == NULL)
	params->geometry = gaiaAllocGeomColl ();

    pt = dyn_line->First;
    while (pt)
      {
	  /* inserting any POINT */
	  gaiaAddPointToGeomColl (params->geometry, pt->X, pt->Y);
	  pt = pt->Next;
      }
    gaiaFreeDynamicLine (dyn_line);
}
Example #10
0
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;
}
Example #11
0
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaCriticalPointFromGEOSmsg (void)
{
/*
/ Attempts to return a Point Geometry extracted from the latest GEOS 
/ error / warning message
*/
    double x;
    double y;
    gaiaGeomCollPtr geom;
    const char *msg = gaia_geos_error_msg;
    if (msg == NULL)
	msg = gaia_geos_warning_msg;
    if (msg == NULL)
	return NULL;
    if (!check_geos_critical_point (msg, &x, &y))
	return NULL;
    geom = gaiaAllocGeomColl ();
    gaiaAddPointToGeomColl (geom, x, y);
    return geom;
}
Example #12
0
static gaiaGeomCollPtr
geoJSON_buildGeomFromPolygonSrid (struct geoJson_data *p_data,
				  gaiaPolygonPtr polygon, int *srid)
{
    gaiaGeomCollPtr geom = NULL;

    /* If no pointers are given, return. */
    if (polygon == NULL)
      {
	  return NULL;
      }

    /* Creates and allocates a geometry collection containing a multipoint. */
    switch (polygon->DimensionModel)
      {
      case GAIA_XY:
	  geom = gaiaAllocGeomColl ();
	  break;
      case GAIA_XY_Z:
	  geom = gaiaAllocGeomCollXYZ ();
	  break;
      }
    if (geom == NULL)
      {
	  return NULL;
      }
    geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);
    geom->DeclaredType = GAIA_POLYGON;
    geom->Srid = *srid;

    /* Stores the location of the first and last polygons in the linked list. */
    geom->FirstPolygon = polygon;
    while (polygon != NULL)
      {
	  geoJsonMapDynClean (p_data, polygon);
	  geom->LastPolygon = polygon;
	  polygon = polygon->Next;
      }
    return geom;
}
Example #13
0
/* 
 * Creates a geometry collection containing 2D (xy) polygons.
 *
 * Parameter first is a gaiaPolygonPtr to the first polygon in a linked list of polygons which should 
 * be added to the collection. All of the polygons in the list must be 2D (xy) polygons. There must be 
 * at least 1 polygon in the list.
 *
 * Returns a pointer to the created geometry collection of 2D polygons. The geometry must have 
 * FirstPolygon pointing to the first polygon in the list pointed by first and LastPolygon pointing 
 * to the last element of the same list. DimensionModel must be GAIA_XY and DimensionType must 
 * be GAIA_TYPE_POLYGON.
 *
 */
static gaiaGeomCollPtr
geoJSON_multipolygon_xy (struct geoJson_data *p_data, gaiaPolygonPtr first)
{
    gaiaPolygonPtr p = first;
    gaiaPolygonPtr p_n;
    int i = 0;
    gaiaPolygonPtr new_polyg;
    gaiaRingPtr i_ring;
    gaiaRingPtr o_ring;
    gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
    geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, geom);

    geom->DeclaredType = GAIA_MULTIPOLYGON;

    while (p)
      {
	  i_ring = p->Exterior;
	  new_polyg =
	      gaiaAddPolygonToGeomColl (geom, i_ring->Points, p->NumInteriors);
	  o_ring = new_polyg->Exterior;
	  gaiaCopyRingCoords (o_ring, i_ring);

	  for (i = 0; i < new_polyg->NumInteriors; i++)
	    {
		i_ring = p->Interiors + i;
		o_ring = gaiaAddInteriorRing (new_polyg, i, i_ring->Points);
		gaiaCopyRingCoords (o_ring, i_ring);
	    }

	  p_n = p->Next;
	  geoJsonMapDynClean (p_data, p);
	  gaiaFreePolygon (p);
	  p = p_n;
      }

    return geom;
}
Example #14
0
static gaiaGeomCollPtr
geoJSON_multilinestring_xy (struct geoJson_data *p_data,
			    gaiaLinestringPtr first)
{
    gaiaLinestringPtr p = first;
    gaiaLinestringPtr p_n;
    gaiaLinestringPtr new_line;
    gaiaGeomCollPtr a = gaiaAllocGeomColl ();
    geoJsonMapDynAlloc (p_data, GEOJSON_DYN_GEOMETRY, a);
    a->DeclaredType = GAIA_MULTILINESTRING;
    a->DimensionModel = GAIA_XY;

    while (p)
      {
	  new_line = gaiaAddLinestringToGeomColl (a, p->Points);
	  gaiaCopyLinestringCoords (new_line, p);
	  p_n = p->Next;
	  geoJsonMapDynClean (p_data, p);
	  gaiaFreeLinestring (p);
	  p = p_n;
      }

    return a;
}
Example #15
0
static void
vbbox_read_row (VirtualBBoxCursorPtr cursor)
{
    /* trying to read a row from the BoundingBox real-table */
    struct splite_internal_cache *cache =
        (struct splite_internal_cache *) cursor->pVtab->p_cache;
    sqlite3_stmt *stmt;
    int ret;
    int ic;
    int icx;
    const char *text;
    const unsigned char *blob;
    int size;
    sqlite3_int64 pk;
    double minx;
    double miny;
    double maxx;
    double maxy;
    int srid;
    char ok_minx = 'N';
    char ok_miny = 'N';
    char ok_maxx = 'N';
    char ok_maxy = 'N';
    char ok_srid = 'N';
    stmt = cursor->stmt;
    sqlite3_bind_int64 (stmt, 1, cursor->current_row);
    ret = sqlite3_step (stmt);
    if (ret == SQLITE_ROW)
    {
        pk = sqlite3_column_int64 (stmt, 0);
        if (sqlite3_column_type (stmt, 1) == SQLITE_FLOAT)
        {
            minx = sqlite3_column_double (stmt, 1);
            ok_minx = 'Y';
        }
        if (sqlite3_column_type (stmt, 2) == SQLITE_FLOAT)
        {
            miny = sqlite3_column_double (stmt, 2);
            ok_miny = 'Y';
        }
        if (sqlite3_column_type (stmt, 3) == SQLITE_FLOAT)
        {
            maxx = sqlite3_column_double (stmt, 3);
            ok_maxx = 'Y';
        }
        if (sqlite3_column_type (stmt, 4) == SQLITE_FLOAT)
        {
            maxy = sqlite3_column_double (stmt, 4);
            ok_maxy = 'Y';
        }
        if (sqlite3_column_type (stmt, 5) == SQLITE_INTEGER)
        {
            srid = sqlite3_column_int (stmt, 5);
            ok_srid = 'Y';
        }
        if (cursor->pVtab->BBoxGeom)
            gaiaFreeGeomColl (cursor->pVtab->BBoxGeom);
        cursor->pVtab->BBoxGeom = NULL;
        if (ok_minx == 'Y' && ok_miny == 'Y' && ok_maxx == 'Y'
                && ok_maxy == 'Y')
        {
            gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
            gaiaPolygonPtr pg = gaiaAddPolygonToGeomColl (geom, 5, 0);
            gaiaRingPtr rng = pg->Exterior;
            gaiaSetPoint (rng->Coords, 0, minx, miny);
            gaiaSetPoint (rng->Coords, 1, maxx, miny);
            gaiaSetPoint (rng->Coords, 2, maxx, maxy);
            gaiaSetPoint (rng->Coords, 3, minx, maxy);
            gaiaSetPoint (rng->Coords, 4, minx, miny);
            if (ok_srid == 'Y')
            {
                if (cursor->pVtab->ForceWGS84)
                {
                    /* converting to WGS84 long-lat */
                    gaiaGeomCollPtr geom2 = NULL;
                    char *proj_from = NULL;
                    char *proj_to = NULL;
                    geom->Srid = srid;
                    getProjParams (cursor->pVtab->db, srid, &proj_from);
                    getProjParams (cursor->pVtab->db, 4326, &proj_to);
                    if (proj_to == NULL || proj_from == NULL)
                        geom2 = NULL;
                    else
#ifndef OMIT_PROJ		/* including PROJ.4 */
                        if (cache != NULL)
                            geom2 =
                                gaiaTransform_r (cache, geom, proj_from,
                                                 proj_to);
                        else
                            geom2 =
                                gaiaTransform (geom, proj_from, proj_to);
#endif /* end including PROJ.4 */
                    geom2 = NULL;
                    if (geom2 != NULL)
                        geom2->Srid = 4326;
                    cursor->pVtab->BBoxGeom = geom2;
                    gaiaFreeGeomColl (geom);
                    if (proj_from)
                        free (proj_from);
                    if (proj_to)
                        free (proj_to);
                }
                else
                {
                    geom->Srid = srid;
                    cursor->pVtab->BBoxGeom = geom;
                }
            }
            else
            {
                geom->Srid = cursor->pVtab->Srid;
                cursor->pVtab->BBoxGeom = geom;
            }
        }
        icx = 5;
        for (ic = 0; ic < cursor->pVtab->nColumns; ic++)
        {
            if (*(cursor->pVtab->Visible + ic) != 'Y')
                continue;
            icx++;
            switch (sqlite3_column_type (stmt, icx))
            {
            case SQLITE_INTEGER:
                value_set_int (*(cursor->pVtab->Value + ic),
                               sqlite3_column_int64 (stmt, icx));
                break;
            case SQLITE_FLOAT:
                value_set_double (*(cursor->pVtab->Value + ic),
                                  sqlite3_column_double (stmt, icx));
                break;
            case SQLITE_TEXT:
                text = (char *) sqlite3_column_text (stmt, icx);
                size = sqlite3_column_bytes (stmt, icx);
                value_set_text (*(cursor->pVtab->Value + ic), text, size);
                break;
            case SQLITE_BLOB:
                blob = sqlite3_column_blob (stmt, icx);
                size = sqlite3_column_bytes (stmt, icx);
                value_set_blob (*(cursor->pVtab->Value + ic), blob, size);
                break;
            case SQLITE_NULL:
            default:
                value_set_null (*(cursor->pVtab->Value + ic));
                break;
            };
        }
    }
    else
    {
        /* an error occurred */
        cursor->eof = 1;
        return;
    }
    cursor->eof = 0;
    cursor->current_row = pk;
}
Example #16
0
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;
}
Example #17
0
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakeEllipse (double cx, double cy, double x_axis, double y_axis,
		 double step)
{
/* return a Linestring approximating an Ellipse */
    gaiaDynamicLinePtr dyn;
    double x;
    double y;
    double angle = 0.0;
    int points = 0;
    gaiaPointPtr pt;
    gaiaGeomCollPtr geom;
    gaiaLinestringPtr ln;
    int iv = 0;

    if (step < 0.0)
	step *= -1.0;
    if (step == 0.0)
	step = 10.0;
    if (step < 0.1)
	step = 0.1;
    if (step > 45.0)
	step = 45.0;
    if (x_axis < 0.0)
	x_axis *= -1.0;
    if (y_axis < 0.0)
	y_axis *= -1.0;
    dyn = gaiaAllocDynamicLine ();
    while (angle < 360.0)
      {
	  double rads = angle * .0174532925199432958;
	  x = cx + (x_axis * cos (rads));
	  y = cy + (y_axis * sin (rads));
	  gaiaAppendPointToDynamicLine (dyn, x, y);
	  angle += step;
      }
/* closing the ellipse */
    gaiaAppendPointToDynamicLine (dyn, dyn->First->X, dyn->First->Y);

    pt = dyn->First;
    while (pt)
      {
	  /* counting how many points */
	  points++;
	  pt = pt->Next;
      }
    if (points == 0)
      {
	  gaiaFreeDynamicLine (dyn);
	  return NULL;
      }

    geom = gaiaAllocGeomColl ();
    ln = gaiaAddLinestringToGeomColl (geom, points);
    pt = dyn->First;
    while (pt)
      {
	  /* setting Vertices */
	  gaiaSetPoint (ln->Coords, iv, pt->X, pt->Y);
	  iv++;
	  pt = pt->Next;
      }
    gaiaFreeDynamicLine (dyn);
    return geom;
}
Example #18
0
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;
}
Example #19
0
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaMakeEllipticArc (double cx,
		     double cy, double x_axis, double y_axis, double start,
		     double stop, double step)
{
/* return a Linestring approximating an Elliptic Arc */
    gaiaDynamicLinePtr dyn;
    double x;
    double y;
    double angle;
    double rads;
    int points = 0;
    gaiaPointPtr pt;
    gaiaGeomCollPtr geom;
    gaiaLinestringPtr ln;
    int iv = 0;

    if (step < 0.0)
	step *= -1.0;
    if (step == 0.0)
	step = 10.0;
    if (step < 0.1)
	step = 0.1;
    if (step > 45.0)
	step = 45.0;
    if (x_axis < 0.0)
	x_axis *= -1.0;
    if (y_axis < 0.0)
	y_axis *= -1.0;
/* normalizing Start/Stop angles */
    while (start >= 360.0)
	start -= 360.0;
    while (start <= -720.0)
	start += 360;
    while (stop >= 360.0)
	stop -= 360.0;
    while (stop <= -720.0)
	stop += 360;
    if (start < 0.0)
	start = 360.0 + start;
    if (stop < 0.0)
	stop = 360.0 + stop;
    if (start > stop)
	stop += 360.0;

    dyn = gaiaAllocDynamicLine ();
    angle = start;
    while (angle < stop)
      {
	  rads = angle * .0174532925199432958;
	  x = cx + (x_axis * cos (rads));
	  y = cy + (y_axis * sin (rads));
	  gaiaAppendPointToDynamicLine (dyn, x, y);
	  angle += step;
      }
/* closing the arc */
    rads = stop * .0174532925199432958;
    x = cx + (x_axis * cos (rads));
    y = cy + (y_axis * sin (rads));
    if (x != dyn->Last->X || y != dyn->Last->Y)
	gaiaAppendPointToDynamicLine (dyn, x, y);

    pt = dyn->First;
    while (pt)
      {
	  /* counting how many points */
	  points++;
	  pt = pt->Next;
      }
    if (points == 0)
      {
	  gaiaFreeDynamicLine (dyn);
	  return NULL;
      }

    geom = gaiaAllocGeomColl ();
    ln = gaiaAddLinestringToGeomColl (geom, points);
    pt = dyn->First;
    while (pt)
      {
	  /* setting Vertices */
	  gaiaSetPoint (ln->Coords, iv, pt->X, pt->Y);
	  iv++;
	  pt = pt->Next;
      }
    gaiaFreeDynamicLine (dyn);
    return geom;
}
Example #20
0
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;
}
Example #21
0
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;
}
static void
polygon_set_up (struct gml_params *params)
{
/* setting up the latest Polygon (if any) */
    int iv;
    int ib;
    int interiors;
    struct gml_rings_list *rg;
    gaiaDynamicLinePtr dyn_line;
    gaiaPointPtr pt;
    gaiaPolygonPtr pg;
    gaiaRingPtr ring;

    if (params->polygon.exterior == NULL)
	return;

    if (params->geometry == NULL)
	params->geometry = gaiaAllocGeomColl ();

/* preliminary recognition */
    dyn_line = params->polygon.exterior;
    iv = 0;
    pt = dyn_line->First;
    while (pt)
      {
	  /* counting how many POINTs are into the Exterior Ring */
	  iv++;
	  pt = pt->Next;
      }
    interiors = 0;
    rg = params->polygon.first;
    while (rg)
      {
	  /* counting how many Interior Rings are there */
	  interiors++;
	  rg = rg->next;
      }
    pg = gaiaAddPolygonToGeomColl (params->geometry, iv, interiors);

/* setting up the Exterior Ring */
    ring = pg->Exterior;
    iv = 0;
    dyn_line = params->polygon.exterior;
    pt = dyn_line->First;
    while (pt)
      {
	  /* inserting any POINT into the Exterior Ring */
	  gaiaSetPoint (ring->Coords, iv, pt->X, pt->Y);
	  iv++;
	  pt = pt->Next;
      }

    ib = 0;
    rg = params->polygon.first;
    while (rg)
      {
	  /* setting up any Interior Ring */
	  dyn_line = params->polygon.exterior;
	  iv = 0;
	  pt = dyn_line->First;
	  while (pt)
	    {
		/* counting how many POINTs are into the Interior Ring */
		iv++;
		pt = pt->Next;
	    }
	  ring = gaiaAddInteriorRing (pg, ib, iv);
	  iv = 0;
	  pt = dyn_line->First;
	  while (pt)
	    {
		/* inserting any POINT into the Interior Ring */
		gaiaSetPoint (ring->Coords, iv, pt->X, pt->Y);
		iv++;
		pt = pt->Next;
	    }
	  rg = rg->next;
	  ib++;
      }
}
Example #23
0
int
main (int argc, char *argv[])
{
    int ret;
    sqlite3 *handle;
    sqlite3_stmt *stmt;
    char sql[256];
    char *err_msg = NULL;
    double x;
    double y;
    int pk;
    int ix;
    int iy;
    gaiaGeomCollPtr geo = NULL;
    unsigned char *blob;
    int blob_size;
    int i;
    char **results;
    int n_rows;
    int n_columns;
    char *count;
    clock_t t0;
    clock_t t1;
    void *cache;


    if (argc != 2)
      {
	  fprintf (stderr, "usage: %s test_db_path\n", argv[0]);
	  return -1;
      }


/* 
trying to connect the test DB: 
- this demo is intended to create a new, empty database
*/
    ret = sqlite3_open_v2 (argv[1], &handle,
			   SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
    if (ret != SQLITE_OK)
      {
	  printf ("cannot open '%s': %s\n", argv[1], sqlite3_errmsg (handle));
	  sqlite3_close (handle);
	  return -1;
      }
    cache = spatialite_alloc_connection ();
    spatialite_init_ex (handle, cache, 0);


/* showing the SQLite version */
    printf ("SQLite version: %s\n", sqlite3_libversion ());
/* showing the SpatiaLite version */
    printf ("SpatiaLite version: %s\n", spatialite_version ());
    printf ("\n\n");


/* 
we are supposing this one is an empty database,
so we have to create the Spatial Metadata
*/
    strcpy (sql, "SELECT InitSpatialMetadata(1)");
    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK)
      {
/* an error occurred */
	  printf ("InitSpatialMetadata() error: %s\n", err_msg);
	  sqlite3_free (err_msg);
	  goto abort;
      }


/*
now we can create the test table
for simplicity we'll define only one column, the primary key
*/
    strcpy (sql, "CREATE TABLE test (");
    strcat (sql, "PK INTEGER NOT NULL PRIMARY KEY)");
    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK)
      {
/* an error occurred */
	  printf ("CREATE TABLE 'test' error: %s\n", err_msg);
	  sqlite3_free (err_msg);
	  goto abort;
      }


/*
... we'll add a Geometry column of POINT type to the test table 
*/
    strcpy (sql, "SELECT AddGeometryColumn('test', 'geom', 3003, 'POINT', 2)");
    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK)
      {
/* an error occurred */
	  printf ("AddGeometryColumn() error: %s\n", err_msg);
	  sqlite3_free (err_msg);
	  goto abort;
      }


/*
and finally we'll enable this geo-column to have a Spatial Index based on R*Tree
*/
    strcpy (sql, "SELECT CreateSpatialIndex('test', 'geom')");
    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK)
      {
/* an error occurred */
	  printf ("CreateSpatialIndex() error: %s\n", err_msg);
	  sqlite3_free (err_msg);
	  goto abort;
      }

    printf
	("\nnow we are going to insert 1 million POINTs; wait, please ...\n\n");

    t0 = clock ();
/*
beginning a transaction

*** this step is absolutely critical ***

the SQLite engine is a TRANSACTIONAL one
the whole batch of INSERTs has to be performed as an unique transaction,
otherwise performance will be surely very poor
*/
    strcpy (sql, "BEGIN");
    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK)
      {
/* an error occurred */
	  printf ("BEGIN error: %s\n", err_msg);
	  sqlite3_free (err_msg);
	  goto abort;
      }



/* 
preparing to populate the test table
we'll use a Prepared Statement we can reuse in order to insert each row
*/
    strcpy (sql, "INSERT INTO test (pk, geom) VALUES (?, ?)");
    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
    if (ret != SQLITE_OK)
      {
/* an error occurred */
	  printf ("INSERT SQL error: %s\n", sqlite3_errmsg (handle));
	  goto abort;
      }

    pk = 0;
    for (ix = 0; ix < 1000; ix++)
      {
	  x = 1000000.0 + (ix * 10.0);
	  for (iy = 0; iy < 1000; iy++)
	    {
/* this double loop will insert 1 million rows into the the test table */

		y = 4000000.0 + (iy * 10.0);
		pk++;
		if ((pk % 25000) == 0)
		  {
		      t1 = clock ();
		      printf ("insert row: %d\t\t[elapsed time: %1.3f]\n",
			      pk, (double) (t1 - t0) / CLOCKS_PER_SEC);
		  }

/* preparing the geometry to insert */
		geo = gaiaAllocGeomColl ();
		geo->Srid = 3003;
		gaiaAddPointToGeomColl (geo, x, y);

/* transforming this geometry into the SpatiaLite BLOB format */
		gaiaToSpatiaLiteBlobWkb (geo, &blob, &blob_size);

/* we can now destroy the geometry object */
		gaiaFreeGeomColl (geo);

/* resetting Prepared Statement and bindings */
		sqlite3_reset (stmt);
		sqlite3_clear_bindings (stmt);

/* binding parameters to Prepared Statement */
		sqlite3_bind_int64 (stmt, 1, pk);
		sqlite3_bind_blob (stmt, 2, blob, blob_size, free);

/* performing actual row insert */
		ret = sqlite3_step (stmt);
		if (ret == SQLITE_DONE || ret == SQLITE_ROW)
		    ;
		else
		  {
/* an unexpected error occurred */
		      printf ("sqlite3_step() error: %s\n",
			      sqlite3_errmsg (handle));
		      sqlite3_finalize (stmt);
		      goto abort;
		  }

	    }
      }
/* we have now to finalize the query [memory cleanup] */
    sqlite3_finalize (stmt);



/*
committing the transaction

*** this step is absolutely critical ***

if we don't confirm the still pending transaction,
any update will be lost
*/
    strcpy (sql, "COMMIT");
    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK)
      {
/* an error occurred */
	  printf ("COMMIT error: %s\n", err_msg);
	  sqlite3_free (err_msg);
	  goto abort;
      }



/*
now we'll optimize the table
*/
    strcpy (sql, "ANALYZE test");
    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK)
      {
/* an error occurred */
	  printf ("ANALYZE error: %s\n", err_msg);
	  sqlite3_free (err_msg);
	  goto abort;
      }


    for (ix = 0; ix < 3; ix++)
      {
	  printf ("\nperforming test#%d - not using Spatial Index\n", ix);
/* 
now we'll perform the spatial query WITHOUT using the Spatial Index
we'll loop 3 times in order to avoid buffering-caching side effects
*/
	  strcpy (sql, "SELECT Count(*) FROM test ");
	  strcat (sql, "WHERE MbrWithin(geom, BuildMbr(");
	  strcat (sql, "1000400.5, 4000400.5, ");
	  strcat (sql, "1000450.5, 4000450.5))");
	  t0 = clock ();
	  ret = sqlite3_get_table (handle, sql, &results, &n_rows, &n_columns,
				   &err_msg);
	  if (ret != SQLITE_OK)
	    {
/* an error occurred */
		printf ("NoSpatialIndex SQL error: %s\n", err_msg);
		sqlite3_free (err_msg);
		goto abort;
	    }
	  count = "";
	  for (i = 1; i <= n_rows; i++)
	    {
		count = results[(i * n_columns) + 0];
	    }
	  t1 = clock ();
	  printf ("Count(*) = %d\t\t[elapsed time: %1.4f]\n", atoi (count),
		  (double) (t1 - t0) / CLOCKS_PER_SEC);
/* we can now free the table results */
	  sqlite3_free_table (results);
      }


    for (ix = 0; ix < 3; ix++)
      {
	  printf ("\nperforming test#%d - using the R*Tree Spatial Index\n",
		  ix);
/* 
now we'll perform the spatial query USING the R*Tree Spatial Index
we'll loop 3 times in order to avoid buffering-caching side effects
*/
	  strcpy (sql, "SELECT Count(*) FROM test ");
	  strcat (sql, "WHERE MbrWithin(geom, BuildMbr(");
	  strcat (sql, "1000400.5, 4000400.5, ");
	  strcat (sql, "1000450.5, 4000450.5)) AND ROWID IN (");
	  strcat (sql, "SELECT pkid FROM idx_test_geom WHERE ");
	  strcat (sql, "xmin > 1000400.5 AND ");
	  strcat (sql, "xmax < 1000450.5 AND ");
	  strcat (sql, "ymin > 4000400.5 AND ");
	  strcat (sql, "ymax < 4000450.5)");
/*
YES, this query is a very unhappy one
the idea is simply to simulate exactly the same conditions as above
*/
	  t0 = clock ();
	  ret = sqlite3_get_table (handle, sql, &results, &n_rows, &n_columns,
				   &err_msg);
	  if (ret != SQLITE_OK)
	    {
/* an error occurred */
		printf ("SpatialIndex SQL error: %s\n", err_msg);
		sqlite3_free (err_msg);
		goto abort;
	    }
	  count = "";
	  for (i = 1; i <= n_rows; i++)
	    {
		count = results[(i * n_columns) + 0];
	    }
	  t1 = clock ();
	  printf ("Count(*) = %d\t\t[elapsed time: %1.4f]\n", atoi (count),
		  (double) (t1 - t0) / CLOCKS_PER_SEC);
/* we can now free the table results */
	  sqlite3_free_table (results);
      }


/* disconnecting the test DB */
    ret = sqlite3_close (handle);
    if (ret != SQLITE_OK)
      {
	  printf ("close() error: %s\n", sqlite3_errmsg (handle));
	  return -1;
      }
    spatialite_cleanup_ex (cache);
    printf ("\n\nsample successfully terminated\n");
    return 0;

  abort:
    sqlite3_close (handle);
    spatialite_cleanup_ex (cache);
    spatialite_shutdown();
    return -1;
}
Example #24
0
static int
kml_parse_polygon (struct kml_data *p_data, gaiaGeomCollPtr geom,
		   kmlNodePtr node, kmlNodePtr * next_n)
{
/* parsing a <Polygon> */
    int interior;
    int has_z;
    int inners;
    int outers;
    int points;
    int iv;
    int ib = 0;
    gaiaGeomCollPtr pg;
    gaiaGeomCollPtr last_g;
    gaiaPolygonPtr new_pg;
    gaiaRingPtr ring;
    gaiaDynamicLinePtr dyn;
    gaiaPointPtr pt;
    gaiaDynamicLinePtr exterior_ring;
    kmlNodePtr next;
    kmlDynamicRingPtr dyn_rng;
    kmlDynamicPolygonPtr dyn_pg = kml_alloc_dyn_polygon (p_data);
    kmlNodePtr n = node;
    while (n)
      {
	  /* looping on rings */
	  if (strcmp (n->Tag, "Polygon") == 0)
	    {
		*next_n = n->Next;
		break;
	    }
	  dyn = kml_parse_ring (n, &interior, &has_z, &next);
	  if (dyn == NULL)
	      goto error;
	  if (kml_count_dyn_points (dyn) < 4)
	    {
		/* cannot be a valid ring */
		goto error;
	    }
	  /* checking if the ring is closed */
	  if (has_z)
	    {
		if (dyn->First->X == dyn->Last->X
		    && dyn->First->Y == dyn->Last->Y
		    && dyn->First->Z == dyn->Last->Z)
		    ;
		else
		    goto error;
	    }
	  else
	    {
		if (dyn->First->X == dyn->Last->X
		    && dyn->First->Y == dyn->Last->Y)
		    ;
		else
		    goto error;
	    }
	  kml_add_polygon_ring (dyn_pg, dyn, interior, has_z);
	  n = next;
      }
/* ok, KML nodes match as expected */
    inners = 0;
    outers = 0;
    has_z = 1;
    dyn_rng = dyn_pg->first;
    while (dyn_rng)
      {
	  /* verifying the rings collection */
	  if (dyn_rng->has_z == 0)
	      has_z = 0;
	  if (dyn_rng->interior)
	      inners++;
	  else
	    {
		outers++;
		points = kml_count_dyn_points (dyn_rng->ring);
		exterior_ring = dyn_rng->ring;
	    }
	  dyn_rng = dyn_rng->next;
      }
    if (outers != 1)		/* no exterior ring declared */
	goto error;

    if (has_z)
      {
	  pg = gaiaAllocGeomCollXYZ ();
	  kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg);
	  new_pg = gaiaAddPolygonToGeomColl (pg, points, inners);
	  /* initializing the EXTERIOR RING */
	  ring = new_pg->Exterior;
	  pt = exterior_ring->First;
	  iv = 0;
	  while (pt)
	    {
		gaiaSetPointXYZ (ring->Coords, iv, pt->X, pt->Y, pt->Z);
		iv++;
		pt = pt->Next;
	    }
	  dyn_rng = dyn_pg->first;
	  while (dyn_rng)
	    {
		/* initializing any INTERIOR RING */
		if (dyn_rng->interior == 0)
		  {
		      dyn_rng = dyn_rng->next;
		      continue;
		  }
		points = kml_count_dyn_points (dyn_rng->ring);
		ring = gaiaAddInteriorRing (new_pg, ib, points);
		ib++;
		pt = dyn_rng->ring->First;
		iv = 0;
		while (pt)
		  {
		      gaiaSetPointXYZ (ring->Coords, iv, pt->X, pt->Y, pt->Z);
		      iv++;
		      pt = pt->Next;
		  }
		dyn_rng = dyn_rng->next;
	    }
      }
    else
      {
	  pg = gaiaAllocGeomColl ();
	  kmlMapDynAlloc (p_data, KML_DYN_GEOM, pg);
	  new_pg = gaiaAddPolygonToGeomColl (pg, points, inners);
	  /* initializing the EXTERIOR RING */
	  ring = new_pg->Exterior;
	  pt = exterior_ring->First;
	  iv = 0;
	  while (pt)
	    {
		gaiaSetPoint (ring->Coords, iv, pt->X, pt->Y);
		iv++;
		pt = pt->Next;
	    }
	  dyn_rng = dyn_pg->first;
	  while (dyn_rng)
	    {
		/* initializing any INTERIOR RING */
		if (dyn_rng->interior == 0)
		  {
		      dyn_rng = dyn_rng->next;
		      continue;
		  }
		points = kml_count_dyn_points (dyn_rng->ring);
		ring = gaiaAddInteriorRing (new_pg, ib, points);
		ib++;
		pt = dyn_rng->ring->First;
		iv = 0;
		while (pt)
		  {
		      gaiaSetPoint (ring->Coords, iv, pt->X, pt->Y);
		      iv++;
		      pt = pt->Next;
		  }
		dyn_rng = dyn_rng->next;
	    }
      }

    last_g = geom;
    while (1)
      {
	  /* searching the last Geometry within chain */
	  if (last_g->Next == NULL)
	      break;
	  last_g = last_g->Next;
      }
    last_g->Next = pg;
    kml_free_dyn_polygon (dyn_pg);
    return 1;

  error:
    kml_free_dyn_polygon (dyn_pg);
    return 0;
}
Example #25
0
static int
kml_parse_linestring (struct kml_data *p_data, gaiaGeomCollPtr geom,
		      kmlNodePtr node, kmlNodePtr * next)
{
/* parsing a <LineString> */
    gaiaGeomCollPtr ln;
    gaiaGeomCollPtr last;
    gaiaLinestringPtr new_ln;
    gaiaPointPtr pt;
    int iv;
    int has_z = 1;
    int points = 0;
    gaiaDynamicLinePtr dyn = gaiaAllocDynamicLine ();
    kmlMapDynAlloc (p_data, KML_DYN_DYNLINE, dyn);

    if (strcmp (node->Tag, "coordinates") == 0)
      {
	  /* parsing a KML <LineString> */
	  if (!kml_parse_coordinates (node->Coordinates, dyn, &has_z))
	      goto error;
	  node = node->Next;
	  if (node == NULL)
	      goto error;
	  if (strcmp (node->Tag, "coordinates") == 0)
	      ;
	  else
	      goto error;
	  node = node->Next;
	  if (node == NULL)
	      goto error;
	  if (strcmp (node->Tag, "LineString") == 0)
	      ;
	  else
	      goto error;
	  *next = node->Next;
      }

/* ok, KML nodes match as expected */
    points = kml_count_dyn_points (dyn);
    if (points < 2)
	goto error;
    if (has_z)
      {
	  ln = gaiaAllocGeomCollXYZ ();
	  kmlMapDynAlloc (p_data, KML_DYN_GEOM, ln);
	  new_ln = gaiaAddLinestringToGeomColl (ln, points);
	  pt = dyn->First;
	  iv = 0;
	  while (pt)
	    {
		gaiaSetPointXYZ (new_ln->Coords, iv, pt->X, pt->Y, pt->Z);
		iv++;
		pt = pt->Next;
	    }
      }
    else
      {
	  ln = gaiaAllocGeomColl ();
	  kmlMapDynAlloc (p_data, KML_DYN_GEOM, ln);
	  new_ln = gaiaAddLinestringToGeomColl (ln, points);
	  pt = dyn->First;
	  iv = 0;
	  while (pt)
	    {
		gaiaSetPoint (new_ln->Coords, iv, pt->X, pt->Y);
		iv++;
		pt = pt->Next;
	    }
      }
    last = geom;
    while (1)
      {
	  /* searching the last Geometry within chain */
	  if (last->Next == NULL)
	      break;
	  last = last->Next;
      }
    last->Next = ln;
    gaiaFreeDynamicLine (dyn);
    return 1;

  error:
    gaiaFreeDynamicLine (dyn);
    return 0;
}
Example #26
0
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;
}
Example #27
0
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;
}
Example #28
0
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;
}
Example #29
0
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;
}
Example #30
0
GAIAGEO_DECLARE gaiaGeomCollPtr
gaiaTriangularGrid (gaiaGeomCollPtr geom, double origin_x, double origin_y,
		    double size, int edges_only)
{
/* creating a regular grid [Triangular cells] */
    double min_x;
    double min_y;
    double max_x;
    double max_y;
    double base_x;
    double base_y;
    double x1;
    double y1;
    double x2;
    double y2;
    double x3;
    double y3;
    double x4;
    double y4;
    int count = 0;
    int odd_even = 0;
    gaiaPolygonPtr pg;
    gaiaRingPtr rng;
    gaiaLinestringPtr ln;
    gaiaGeomCollPtr result = NULL;
    gaiaGeomCollPtr item = NULL;

    if (size <= 0.0)
	return NULL;

    result = gaiaAllocGeomColl ();
    result->Srid = geom->Srid;
    get_grid_bbox (geom, &min_x, &min_y, &max_x, &max_y);
    get_grid_base (min_x, min_y, origin_x, origin_y, size, &base_x, &base_y);
    while (base_y < max_y)
      {
	  /* looping on grid rows */
	  if (odd_even)
	      x1 = base_x - (size / 2.0);
	  else
	      x1 = base_x;
	  y1 = base_y;
	  x2 = x1 + size;
	  y2 = y1;
	  x3 = x1 + (size / 2.0);
	  y3 = y1 + (size * sin (3.14159265358979323846 / 3.0));
	  x4 = x3 + size;
	  y4 = y3;
	  while (x1 < max_x)
	    {
		/* looping on grid columns */
		item = gaiaAllocGeomColl ();

		pg = gaiaAddPolygonToGeomColl (item, 4, 0);
		rng = pg->Exterior;
		gaiaSetPoint (rng->Coords, 0, x1, y1);
		gaiaSetPoint (rng->Coords, 1, x2, y2);
		gaiaSetPoint (rng->Coords, 2, x3, y3);
		gaiaSetPoint (rng->Coords, 3, x1, y1);

		gaiaMbrGeometry (item);
		if (gaiaGeomCollIntersects (geom, item) == 1)
		  {
		      /* ok, inserting a valid cell [pointing upside] */
		      count++;
		      if (edges_only)
			{
			    /* multilinestring */
			    ln = gaiaAddLinestringToGeomColl (result, 2);
			    gaiaSetPoint (ln->Coords, 0, x1, y1);
			    gaiaSetPoint (ln->Coords, 1, x2, y2);
			    ln = gaiaAddLinestringToGeomColl (result, 2);
			    gaiaSetPoint (ln->Coords, 0, x2, y2);
			    gaiaSetPoint (ln->Coords, 1, x3, y3);
			    ln = gaiaAddLinestringToGeomColl (result, 2);
			    gaiaSetPoint (ln->Coords, 0, x3, y3);
			    gaiaSetPoint (ln->Coords, 1, x1, y1);
			}
		      else
			{
			    /* polygon */
			    pg = gaiaAddPolygonToGeomColl (result, 4, 0);
			    rng = pg->Exterior;
			    gaiaSetPoint (rng->Coords, 0, x1, y1);
			    gaiaSetPoint (rng->Coords, 1, x2, y2);
			    gaiaSetPoint (rng->Coords, 2, x3, y3);
			    gaiaSetPoint (rng->Coords, 3, x1, y1);
			}
		  }
		gaiaFreeGeomColl (item);

		item = gaiaAllocGeomColl ();

		pg = gaiaAddPolygonToGeomColl (item, 4, 0);
		rng = pg->Exterior;
		gaiaSetPoint (rng->Coords, 0, x3, y3);
		gaiaSetPoint (rng->Coords, 1, x2, y2);
		gaiaSetPoint (rng->Coords, 2, x4, y4);
		gaiaSetPoint (rng->Coords, 3, x3, y3);

		gaiaMbrGeometry (item);
		if (gaiaGeomCollIntersects (geom, item) == 1)
		  {
		      /* ok, inserting a valid cell [pointing downside] */
		      count++;
		      if (edges_only)
			{
			    /* multilinestring */
			    ln = gaiaAddLinestringToGeomColl (result, 2);
			    gaiaSetPoint (ln->Coords, 0, x1, y1);
			    gaiaSetPoint (ln->Coords, 1, x2, y2);
			    ln = gaiaAddLinestringToGeomColl (result, 2);
			    gaiaSetPoint (ln->Coords, 0, x2, y2);
			    gaiaSetPoint (ln->Coords, 1, x3, y3);
			    ln = gaiaAddLinestringToGeomColl (result, 2);
			    gaiaSetPoint (ln->Coords, 0, x3, y3);
			    gaiaSetPoint (ln->Coords, 1, x1, y1);
			}
		      else
			{
			    /* polygon */
			    pg = gaiaAddPolygonToGeomColl (result, 4, 0);
			    rng = pg->Exterior;
			    gaiaSetPoint (rng->Coords, 0, x3, y3);
			    gaiaSetPoint (rng->Coords, 1, x2, y2);
			    gaiaSetPoint (rng->Coords, 2, x4, y4);
			    gaiaSetPoint (rng->Coords, 3, x3, y3);
			}
		  }
		gaiaFreeGeomColl (item);

		x1 += size;
		x2 += size;
		x3 += size;
		x4 += size;
	    }
	  base_y += (size * sin (3.14159265358979323846 / 3.0));
	  if (odd_even)
	      odd_even = 0;
	  else
	      odd_even = 1;
      }

/* final check */
    if (!count)
      {
	  /* empty grid */
	  gaiaFreeGeomColl (result);
	  return NULL;
      }
    if (!edges_only)
      {
	  result->DeclaredType = GAIA_MULTIPOLYGON;
	  return result;
      }

    item = result;
    result = gaiaUnaryUnion (item);
    gaiaFreeGeomColl (item);
    result->Srid = geom->Srid;
    result->DeclaredType = GAIA_LINESTRING;
    return result;
}