Exemple #1
0
static int 
ptarray_to_kml2_sb(const POINTARRAY *pa, int precision, stringbuffer_t *sb)
{
	int i, j;
	int dims = FLAGS_GET_Z(pa->flags) ? 3 : 2;
	POINT4D pt;
	double *d;
	
	for ( i = 0; i < pa->npoints; i++ )
	{
		getPoint4d_p(pa, i, &pt);
		d = (double*)(&pt);
		if ( i ) stringbuffer_append(sb," ");
		for (j = 0; j < dims; j++)
		{
			if ( j ) stringbuffer_append(sb,",");
			if( fabs(d[j]) < OUT_MAX_DOUBLE )
			{
				if ( stringbuffer_aprintf(sb, "%.*f", precision, d[j]) < 0 ) return LW_FAILURE;
			}
			else 
			{
				if ( stringbuffer_aprintf(sb, "%g", d[j]) < 0 ) return LW_FAILURE;
			}
			stringbuffer_trim_trailing_zeroes(sb);
		}
	}
	return LW_SUCCESS;
}
Exemple #2
0
char *
pc_point_to_string(const PCPOINT *pt)
{
	/* { "pcid":1, "values":[<dim1>, <dim2>, <dim3>, <dim4>] }*/
	stringbuffer_t *sb = stringbuffer_create();
	char *str;
	int i;

	stringbuffer_aprintf(sb, "{\"pcid\":%d,\"pt\":[", pt->schema->pcid);
	for ( i = 0; i < pt->schema->ndims; i++ )
	{
		double d;
		if ( ! pc_point_get_double_by_index(pt, i, &d) )
		{
			pcerror("pc_point_to_string: unable to read double at position %d", i);
		}
		if ( i )
		{
			stringbuffer_append(sb, ",");
		}
		stringbuffer_aprintf(sb, "%g", d);
	}
	stringbuffer_append(sb, "]}");
	str = stringbuffer_getstringcopy(sb);
	stringbuffer_destroy(sb);
	return str;
}
Exemple #3
0
static int 
lwpoint_to_kml2_sb(const LWPOINT *point, int precision, const char *prefix, stringbuffer_t *sb)
{
	/* Open point */
	if ( stringbuffer_aprintf(sb, "<%sPoint><%scoordinates>", prefix, prefix) < 0 ) return LW_FAILURE;
	/* Coordinate array */
	if ( ptarray_to_kml2_sb(point->point, precision, sb) == LW_FAILURE ) return LW_FAILURE;
	/* Close point */
	if ( stringbuffer_aprintf(sb, "</%scoordinates></%sPoint>", prefix, prefix) < 0 ) return LW_FAILURE;
	return LW_SUCCESS;
}
Exemple #4
0
static int 
lwline_to_kml2_sb(const LWLINE *line, int precision, const char *prefix, stringbuffer_t *sb)
{
	/* Open linestring */
	if ( stringbuffer_aprintf(sb, "<%sLineString><%scoordinates>", prefix, prefix) < 0 ) return LW_FAILURE;
	/* Coordinate array */
	if ( ptarray_to_kml2_sb(line->points, precision, sb) == LW_FAILURE ) return LW_FAILURE;
	/* Close linestring */
	if ( stringbuffer_aprintf(sb, "</%scoordinates></%sLineString>", prefix, prefix) < 0 ) return LW_FAILURE;
	
	return LW_SUCCESS;
}
char * pc_patch_dimensional_bytes_array_to_string(PCPATCH_DIMENSIONAL* pd)
{
	int i;
	char *str;
	stringbuffer_t *sb = stringbuffer_create();
	
	
	stringbuffer_append(sb, "{");

	if ( pd->schema->ndims )
	{

		stringbuffer_append(sb, "\"bytes\" : [\n");

		for ( i = 0; i < pd->schema->ndims; i++ )
		{
			if ( pd->bytes[i].bytes )
			{
				PCBYTES *d = &pd->bytes[i];

				if ( i ) stringbuffer_append(sb, ",");
				stringbuffer_append(sb, "\n { \n");

				stringbuffer_aprintf(sb, " %s ",  pc_bytes_to_string(d));
				stringbuffer_append(sb, " }");
			}
		}
		stringbuffer_append(sb, "\n]\n");
	}
	stringbuffer_append(sb, "}\n");
	str = stringbuffer_getstringcopy(sb);
	stringbuffer_destroy(sb);
	return str;
}
/* Return a pointer to an allocated string containing the header for the specified loader state */
int
ShpLoaderGetSQLFooter(SHPLOADERSTATE *state, char **strfooter)
{
	stringbuffer_t *sb;
	char *ret;

	/* Create the stringbuffer containing the header; we use this API as it's easier
	   for handling string resizing during append */
	sb = stringbuffer_create();
	stringbuffer_clear(sb);

	/* Create gist index if specified and not in "prepare" mode */
	if (state->config->readshape && state->config->createindex)
	{
		stringbuffer_aprintf(sb, "CREATE INDEX ON ");
		/* Schema is optional, include if present. */
		if (state->config->schema)
		{
			stringbuffer_aprintf(sb, "\"%s\".",state->config->schema);
		}
		stringbuffer_aprintf(sb, "\"%s\" USING GIST (\"%s\")", state->config->table, state->geo_col);
		/* Tablespace is also optional. */
		if (state->config->idxtablespace != NULL)
		{
			stringbuffer_aprintf(sb, " TABLESPACE \"%s\"", state->config->idxtablespace);
		}
		stringbuffer_aprintf(sb, ";\n");
	}

	/* End the transaction if there is one. */
	if (state->config->usetransaction)
	{
		stringbuffer_aprintf(sb, "COMMIT;\n");
	}

	/* Always ANALYZE the resulting table, for better stats */
	stringbuffer_aprintf(sb, "ANALYZE ");
	if (state->config->schema)
	{
		stringbuffer_aprintf(sb, "\"%s\".", state->config->schema);
	}
	stringbuffer_aprintf(sb, "\"%s\";\n", state->config->table);

	/* Copy the string buffer into a new string, destroying the string buffer */
	ret = (char *)malloc(strlen((char *)stringbuffer_getstring(sb)) + 1);
	strcpy(ret, (char *)stringbuffer_getstring(sb));
	stringbuffer_destroy(sb);

	*strfooter = ret;

	return SHPLOADEROK;
}
Exemple #7
0
static int 
lwcollection_to_kml2_sb(const LWCOLLECTION *col, int precision, const char *prefix, stringbuffer_t *sb)
{
	int i, rv;
		
	/* Open geometry */
	if ( stringbuffer_aprintf(sb, "<%sMultiGeometry>", prefix) < 0 ) return LW_FAILURE;
	for ( i = 0; i < col->ngeoms; i++ )
	{
		rv = lwgeom_to_kml2_sb(col->geoms[i], precision, prefix, sb);
		if ( rv == LW_FAILURE ) return LW_FAILURE;		
	}
	/* Close geometry */
	if ( stringbuffer_aprintf(sb, "</%sMultiGeometry>", prefix) < 0 ) return LW_FAILURE;

	return LW_SUCCESS;
}
Exemple #8
0
static int 
lwpoly_to_kml2_sb(const LWPOLY *poly, int precision, const char *prefix, stringbuffer_t *sb)
{
	int i, rv;
	
	/* Open polygon */
	if ( stringbuffer_aprintf(sb, "<%sPolygon>", prefix) < 0 ) return LW_FAILURE;
	for ( i = 0; i < poly->nrings; i++ )
	{
		/* Inner or outer ring opening tags */
		if( i )
			rv = stringbuffer_aprintf(sb, "<%sinnerBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);
		else
			rv = stringbuffer_aprintf(sb, "<%souterBoundaryIs><%sLinearRing><%scoordinates>", prefix, prefix, prefix);		
		if ( rv < 0 ) return LW_FAILURE;
		
		/* Coordinate array */
		if ( ptarray_to_kml2_sb(poly->rings[i], precision, sb) == LW_FAILURE ) return LW_FAILURE;
		
		/* Inner or outer ring closing tags */
		if( i )
			rv = stringbuffer_aprintf(sb, "</%scoordinates></%sLinearRing></%sinnerBoundaryIs>", prefix, prefix, prefix);
		else
			rv = stringbuffer_aprintf(sb, "</%scoordinates></%sLinearRing></%souterBoundaryIs>", prefix, prefix, prefix);		
		if ( rv < 0 ) return LW_FAILURE;
	}
	/* Close polygon */
	if ( stringbuffer_aprintf(sb, "</%sPolygon>", prefix) < 0 ) return LW_FAILURE;

	return LW_SUCCESS;
}
static void test_stringbuffer_aprintf(void)
{
	stringbuffer_t *sb;
	const char *str;

	sb = stringbuffer_create_with_size(2);
	stringbuffer_aprintf(sb, "hello %dth world", 14);
	str = stringbuffer_getstring(sb);

	CU_ASSERT_STRING_EQUAL("hello 14th world", str);

	stringbuffer_destroy(sb);
}
/* TODO: expose to API ? Would require also exposing stringbuffer
*  See https://github.com/pgpointcloud/pointcloud/issues/74
*/
static int
pc_patch_uncompressed_to_stringbuffer(const PCPATCH_UNCOMPRESSED *patch, stringbuffer_t *sb)
{
	PCPOINTLIST *pl;
	int i, j;

	/* { "pcid":1, "points":[[<dim1>, <dim2>, <dim3>, <dim4>],[<dim1>, <dim2>, <dim3>, <dim4>]] }*/

	/* TODO: reserve space in buffer ? */

	pl = pc_pointlist_from_uncompressed(patch);
	stringbuffer_aprintf(sb, "{\"pcid\":%d,\"pts\":[", patch->schema->pcid);
	for ( i = 0; i < pl->npoints; i++ )
	{
		PCPOINT *pt = pc_pointlist_get_point(pl, i);
		if ( i ) stringbuffer_append(sb, ",[");
		else stringbuffer_append(sb, "[");
		for ( j = 0; j < pt->schema->ndims; j++ )
		{
			double d;
			if ( ! pc_point_get_double_by_index(pt, j, &d))
			{
				pcerror("%s: unable to read double at index %d", __func__, j);
				return PC_FAILURE;
			}
			if ( j ) stringbuffer_aprintf(sb, ",%g", d);
			else stringbuffer_aprintf(sb, "%g", d);
		}
		stringbuffer_append(sb, "]");
	}
	stringbuffer_append(sb, "]}");

	/* All done, copy and clean up */
	pc_pointlist_free(pl);

	return PC_SUCCESS;
}
Exemple #11
0
/** Convert a PCSCHEMA to a human-readable JSON string */
char *
pc_schema_to_json(const PCSCHEMA *pcs)
{
	int i;
	char *str;
	stringbuffer_t *sb = stringbuffer_create();
	stringbuffer_append(sb, "{");

	if ( pcs->pcid )
		stringbuffer_aprintf(sb, "\"pcid\" : %d,\n", pcs->pcid);
	if ( pcs->ndims )
		stringbuffer_aprintf(sb, "\"ndims\" : %d,\n", pcs->ndims);
	if ( pcs->srid )
		stringbuffer_aprintf(sb, "\"srid\" : %d,\n", pcs->srid);
	if ( pcs->compression )
		stringbuffer_aprintf(sb, "\"compression\" : %d,\n", pcs->compression);
	if ( pcs->size )
		stringbuffer_aprintf(sb, "\"size\" : %zu,\n", pcs->size);
	if ( pcs->x_position>=0 )
		stringbuffer_aprintf(sb, "\"x_position\" : %d,\n", pcs->x_position);
	if ( pcs->y_position >=0)
		stringbuffer_aprintf(sb, "\"y_position\" : %d,\n", pcs->y_position);
	if ( pcs->namehash->entrycount )
		stringbuffer_aprintf(sb, "\"namehash->entrycount\" : %d,\n", pcs->namehash->entrycount);
	if ( pcs->ndims )
	{

		stringbuffer_append(sb, "\"dims\" : [\n");

		for ( i = 0; i < pcs->ndims; i++ )
		{
		 
		  stringbuffer_append(sb,pc_dimension_to_json(pcs->dims[i] ) );  
			 
		}
		stringbuffer_append(sb, "\n]\n");
	}
	stringbuffer_append(sb, "}\n");
	str = stringbuffer_getstringcopy(sb);
	stringbuffer_destroy(sb);
	return str;
}
Exemple #12
0
/**@brief * Convert a PCSDIMENSION to a human-readable JSON string 
 * @param the PCDIMENSION we want to print
 * @return q pointer to the string buff describing the object
 * */
char *
pc_dimension_to_json(const PCDIMENSION *d)
{
	int i;
	char *str;
	stringbuffer_t *sb = stringbuffer_create();
	stringbuffer_append(sb, "{");

	 
			if ( d )
			{
				 

				if ( i ) stringbuffer_append(sb, ",");
				stringbuffer_append(sb, "\n { \n");

				if ( d->name )
					stringbuffer_aprintf(sb, "  \"name\" : \"%s\",\n", d->name);
				if ( d->description )
					stringbuffer_aprintf(sb, "  \"description\" : \"%s\",\n", d->description);

				stringbuffer_aprintf(sb, "  \"size\" : %d,\n", d->size);
				stringbuffer_aprintf(sb, "  \"byteoffset\" : %d,\n", d->byteoffset);
				stringbuffer_aprintf(sb, "  \"scale\" : %g,\n", d->scale);
				stringbuffer_aprintf(sb, "  \"interpretation\" : \"%s\",\n", pc_interpretation_string(d->interpretation));
				stringbuffer_aprintf(sb, "  \"offset\" : %g,\n", d->offset);

				stringbuffer_aprintf(sb, "  \"active\" : %d\n", d->active);
				stringbuffer_append(sb, " }");
			}
		 
	stringbuffer_append(sb, "}\n");
	str = stringbuffer_getstringcopy(sb);
	stringbuffer_destroy(sb);
	return str;
}
Exemple #13
0
/*
* Point array is a list of coordinates. Depending on output mode,
* we may suppress some dimensions. ISO and Extended formats include
* all dimensions. Standard OGC output only includes X/Y coordinates.
*/
static void ptarray_to_wkt_sb(const POINTARRAY *ptarray, stringbuffer_t *sb, int precision, uint8_t variant)
{
    /* OGC only includes X/Y */
    int dimensions = 2;
    int i, j;

    /* ISO and extended formats include all dimensions */
    if ( variant & ( WKT_ISO | WKT_EXTENDED ) )
        dimensions = FLAGS_NDIMS(ptarray->flags);

    /* Opening paren? */
    if ( ! (variant & WKT_NO_PARENS) )
        stringbuffer_append(sb, "(");

    /* Digits and commas */
    for (i = 0; i < ptarray->npoints; i++)
    {
        uint8_t *p = getPoint_internal(ptarray, i);
        double d;

        /* Commas before ever coord but the first */
        if ( i > 0 )
            stringbuffer_append(sb, ",");

        for (j = 0; j < dimensions; j++)
        {
            memcpy(&d, p + j * sizeof(double), sizeof(double));
            /* Spaces before every ordinate but the first */
            if ( j > 0 )
                stringbuffer_append(sb, " ");
            stringbuffer_aprintf(sb, "%.*g", precision, d);
        }
    }

    /* Closing paren? */
    if ( ! (variant & WKT_NO_PARENS) )
        stringbuffer_append(sb, ")");
}
Exemple #14
0
/**
* WKT emitter function. Allocates a new *char and fills it with the WKT
* representation. If size_out is not NULL, it will be set to the size of the
* allocated *char.
*
* @param variant Bitmasked value, accepts one of WKT_ISO, WKT_SFSQL, WKT_EXTENDED.
* @param precision Number of significant digits in the output doubles.
* @param size_out If supplied, will return the size of the returned string,
* including the null terminator.
*/
char* lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
{
    stringbuffer_t *sb;
    char *str = NULL;
    if ( geom == NULL )
        return NULL;
    sb = stringbuffer_create();
    /* Extended mode starts with an "SRID=" section for geoms that have one */
    if ( (variant & WKT_EXTENDED) && lwgeom_has_srid(geom) )
    {
        stringbuffer_aprintf(sb, "SRID=%d;", geom->srid);
    }
    lwgeom_to_wkt_sb(geom, sb, precision, variant);
    if ( stringbuffer_getstring(sb) == NULL )
    {
        lwerror("Uh oh");
        return NULL;
    }
    str = stringbuffer_getstringcopy(sb);
    if ( size_out )
        *size_out = stringbuffer_getlength(sb) + 1;
    stringbuffer_destroy(sb);
    return str;
}
Exemple #15
0
/** Convert a PCSCHEMA to a human-readable JSON string */
char * 
pc_schema_to_json(const PCSCHEMA *pcs)
{
	int i;
	char *str;
	stringbuffer_t *sb = stringbuffer_create();
	stringbuffer_append(sb, "{");
	
	if ( pcs->pcid )
		stringbuffer_aprintf(sb, "\"pcid\" : %d,\n", pcs->pcid);
	if ( pcs->srid )
		stringbuffer_aprintf(sb, "\"srid\" : %d,\n", pcs->srid);
	if ( pcs->compression )
		stringbuffer_aprintf(sb, "\"compression\" : %d,\n", pcs->compression);


	if ( pcs->ndims )
	{
		
		stringbuffer_append(sb, "\"dims\" : [\n");
	
		for ( i = 0; i < pcs->ndims; i++ )
		{
			if ( pcs->dims[i] )
			{
				PCDIMENSION *d = pcs->dims[i];

				if ( i ) stringbuffer_append(sb, ",");
				stringbuffer_append(sb, "\n { \n");

				if ( d->name )
					stringbuffer_aprintf(sb, "  \"name\" : \"%s\",\n", d->name);
				if ( d->description )
					stringbuffer_aprintf(sb, "  \"description\" : \"%s\",\n", d->description);

				stringbuffer_aprintf(sb, "  \"size\" : %d,\n", d->size);
				stringbuffer_aprintf(sb, "  \"byteoffset\" : %d,\n", d->byteoffset);
				stringbuffer_aprintf(sb, "  \"scale\" : %g,\n", d->scale);
				stringbuffer_aprintf(sb, "  \"interpretation\" : \"%s\",\n", pc_interpretation_string(d->interpretation));
				stringbuffer_aprintf(sb, "  \"offset\" : %g,\n", d->offset);

				stringbuffer_aprintf(sb, "  \"active\" : %d\n", d->active);
				stringbuffer_append(sb, " }");
			}
		}
		stringbuffer_append(sb, "\n]\n");
	}
	stringbuffer_append(sb, "}\n");
	str = stringbuffer_getstringcopy(sb);
	stringbuffer_destroy(sb);
	return str;
}
Exemple #16
0
/* Return a pointer to an allocated string containing the header for the specified loader state */
int
ShpLoaderGetSQLHeader(SHPLOADERSTATE *state, char **strheader)
{
	stringbuffer_t *sb;
	char *ret;
	int j;

	/* Create the stringbuffer containing the header; we use this API as it's easier
	   for handling string resizing during append */
	sb = stringbuffer_create();
	stringbuffer_clear(sb);
	
	/* Set the client encoding if required */
	if (state->config->encoding)
	{
		stringbuffer_aprintf(sb, "SET CLIENT_ENCODING TO UTF8;\n");
	}
	
	/* Use SQL-standard string escaping rather than PostgreSQL standard */
	stringbuffer_aprintf(sb, "SET STANDARD_CONFORMING_STRINGS TO ON;\n");

	/* Drop table if requested */
	if (state->config->opt == 'd')
	{
		/**
		 * TODO: if the table has more then one geometry column
		 * 	the DROP TABLE call will leave spurious records in
		 * 	geometry_columns.
		 *
		 * If the geometry column in the table being dropped
		 * does not match 'the_geom' or the name specified with
		 * -g an error is returned by DropGeometryColumn.
		 *
		 * The table to be dropped might not exist.
		 */
		if (state->config->schema)
		{
			if (state->config->readshape == 1 && (! state->config->geography) )
			{
				stringbuffer_aprintf(sb, "SELECT DropGeometryColumn('%s','%s','%s');\n",
				                     state->config->schema, state->config->table, state->geo_col);
			}

			stringbuffer_aprintf(sb, "DROP TABLE \"%s\".\"%s\";\n", state->config->schema,
			                     state->config->table);
		}
		else
		{
			if (state->config->readshape == 1  && (! state->config->geography) )
			{
				stringbuffer_aprintf(sb, "SELECT DropGeometryColumn('','%s','%s');\n",
				                     state->config->table, state->geo_col);
			}

			stringbuffer_aprintf(sb, "DROP TABLE \"%s\";\n", state->config->table);
		}
	}

	/* Start of transaction if we are using one */
	if (state->config->usetransaction)
	{
		stringbuffer_aprintf(sb, "BEGIN;\n");
	}

	/* If not in 'append' mode create the spatial table */
	if (state->config->opt != 'a')
	{
		/*
		* Create a table for inserting the shapes into with appropriate
		* columns and types
		*/
		if (state->config->schema)
		{
			stringbuffer_aprintf(sb, "CREATE TABLE \"%s\".\"%s\" (gid serial",
			                     state->config->schema, state->config->table);
		}
		else
		{
			stringbuffer_aprintf(sb, "CREATE TABLE \"%s\" (gid serial", state->config->table);
		}

		/* Generate the field types based upon the shapefile information */
		for (j = 0; j < state->num_fields; j++)
		{
			stringbuffer_aprintf(sb, ",\n\"%s\" ", state->field_names[j]);

			/* First output the raw field type string */
			stringbuffer_aprintf(sb, "%s", state->pgfieldtypes[j]);
			
			/* Some types do have typmods though... */
			if (!strcmp("varchar", state->pgfieldtypes[j]))
				stringbuffer_aprintf(sb, "(%d)", state->widths[j]);

			if (!strcmp("numeric", state->pgfieldtypes[j]))
			{
				/* Doubles we just allow PostgreSQL to auto-detect the size */
				if (state->types[j] != FTDouble)
					stringbuffer_aprintf(sb, "(%d,0)", state->widths[j]);
			}
		}

		/* Add the geography column directly to the table definition, we don't
		   need to do an AddGeometryColumn() call. */
		if (state->config->readshape == 1 && state->config->geography)
		{
			char *dimschar;

			if (state->pgdims == 4)
				dimschar = "ZM";
			else
				dimschar = "";

			if (state->to_srid != SRID_UNKNOWN && state->to_srid != 4326)
			{
				snprintf(state->message, SHPLOADERMSGLEN, _("Invalid SRID for geography type: %d"), state->to_srid);
				stringbuffer_destroy(sb);
				return SHPLOADERERR;
			}
			stringbuffer_aprintf(sb, ",\n\"%s\" geography(%s%s,%d)", state->geo_col, state->pgtype, dimschar, 4326);
		}
		stringbuffer_aprintf(sb, ")");

		/* Tablespace is optional. */
		if (state->config->tablespace != NULL)
		{
			stringbuffer_aprintf(sb, " TABLESPACE \"%s\"", state->config->tablespace);
		}
		stringbuffer_aprintf(sb, ";\n");

		/* Create the primary key.  This is done separately because the index for the PK needs
                 * to be in the correct tablespace. */

		/* TODO: Currently PostgreSQL does not allow specifying an index to use for a PK (so you get
                 *       a default one called table_pkey) and it does not provide a way to create a PK index
                 *       in a specific tablespace.  So as a hacky solution we create the PK, then move the
                 *       index to the correct tablespace.  Eventually this should be:
		 *           CREATE INDEX table_pkey on table(gid) TABLESPACE tblspc;
                 *           ALTER TABLE table ADD PRIMARY KEY (gid) USING INDEX table_pkey;
		 *       A patch has apparently been submitted to PostgreSQL to enable this syntax, see this thread:
		 *           http://archives.postgresql.org/pgsql-hackers/2011-01/msg01405.php */
		stringbuffer_aprintf(sb, "ALTER TABLE ");

		/* Schema is optional, include if present. */
		if (state->config->schema)
		{
			stringbuffer_aprintf(sb, "\"%s\".",state->config->schema);
		}
		stringbuffer_aprintf(sb, "\"%s\" ADD PRIMARY KEY (gid);\n", state->config->table);

		/* Tablespace is optional for the index. */
		if (state->config->idxtablespace != NULL)
		{
			stringbuffer_aprintf(sb, "ALTER INDEX ");
			if (state->config->schema)
			{
				stringbuffer_aprintf(sb, "\"%s\".",state->config->schema);
			}

			/* WARNING: We're assuming the default "table_pkey" name for the primary
			 *          key index.  PostgreSQL may use "table_pkey1" or similar in the
			 *          case of a name conflict, so you may need to edit the produced
			 *          SQL in this rare case. */
			stringbuffer_aprintf(sb, "\"%s_pkey\" SET TABLESPACE \"%s\";\n",
						state->config->table, state->config->idxtablespace);
		}

		/* Create the geometry column with an addgeometry call */
		if (state->config->readshape == 1 && (!state->config->geography))
		{
			/* If they didn't specify a target SRID, see if they specified a source SRID. */
			int srid = state->to_srid;
			if (state->config->schema)
			{
				stringbuffer_aprintf(sb, "SELECT AddGeometryColumn('%s','%s','%s','%d',",
				                     state->config->schema, state->config->table, state->geo_col, srid);
			}
			else
			{
				stringbuffer_aprintf(sb, "SELECT AddGeometryColumn('','%s','%s','%d',",
				                     state->config->table, state->geo_col, srid);
			}

			stringbuffer_aprintf(sb, "'%s',%d);\n", state->pgtype, state->pgdims);
		}
	}

	/* Copy the string buffer into a new string, destroying the string buffer */
	ret = (char *)malloc(strlen((char *)stringbuffer_getstring(sb)) + 1);
	strcpy(ret, (char *)stringbuffer_getstring(sb));
	stringbuffer_destroy(sb);

	*strheader = ret;

	return SHPLOADEROK;
}
Exemple #17
0
/* Return an allocated string representation of a specified record item */
int
ShpLoaderGenerateSQLRowStatement(SHPLOADERSTATE *state, int item, char **strrecord)
{
	SHPObject *obj = NULL;
	stringbuffer_t *sb;
	stringbuffer_t *sbwarn;
	char val[MAXVALUELEN];
	char *escval;
	char *geometry=NULL, *ret;
	char *utf8str;
	int res, i;
	int rv;

	/* Clear the stringbuffers */
	sbwarn = stringbuffer_create();
	stringbuffer_clear(sbwarn);
	sb = stringbuffer_create();
	stringbuffer_clear(sb);

	/* If we are reading the DBF only and the record has been marked deleted, return deleted record status */
	if (state->config->readshape == 0 && DBFIsRecordDeleted(state->hDBFHandle, item))
	{
		*strrecord = NULL;
		return SHPLOADERRECDELETED;
	}

	/* If we are reading the shapefile, open the specified record */
	if (state->config->readshape == 1)
	{
		obj = SHPReadObject(state->hSHPHandle, item);
		if (!obj)
		{
			snprintf(state->message, SHPLOADERMSGLEN, _("Error reading shape object %d"), item);
			return SHPLOADERERR;
		}

		/* If we are set to skip NULLs, return a NULL record status */
		if (state->config->null_policy == POLICY_NULL_SKIP && obj->nVertices == 0 )
		{
			SHPDestroyObject(obj);

			*strrecord = NULL;
			return SHPLOADERRECISNULL;
		}
	}

	/* If not in dump format, generate the INSERT string */
	if (!state->config->dump_format)
	{
		if (state->config->schema)
		{
			stringbuffer_aprintf(sb, "INSERT INTO \"%s\".\"%s\" %s VALUES (", state->config->schema,
			                     state->config->table, state->col_names);
		}
		else
		{
			stringbuffer_aprintf(sb, "INSERT INTO \"%s\" %s VALUES (", state->config->table,
			                     state->col_names);
		}
	}


	/* Read all of the attributes from the DBF file for this item */
	for (i = 0; i < DBFGetFieldCount(state->hDBFHandle); i++)
	{
		/* Special case for NULL attributes */
		if (DBFIsAttributeNULL(state->hDBFHandle, item, i))
		{
			if (state->config->dump_format)
				stringbuffer_aprintf(sb, "\\N");
			else
				stringbuffer_aprintf(sb, "NULL");
		}
		else
		{
			/* Attribute NOT NULL */
			switch (state->types[i])
			{
			case FTInteger:
			case FTDouble:
				rv = snprintf(val, MAXVALUELEN, "%s", DBFReadStringAttribute(state->hDBFHandle, item, i));
				if (rv >= MAXVALUELEN || rv == -1)
				{
					stringbuffer_aprintf(sbwarn, "Warning: field %d name truncated\n", i);
					val[MAXVALUELEN - 1] = '\0';
				}

				/* If the value is an empty string, change to 0 */
				if (val[0] == '\0')
				{
					val[0] = '0';
					val[1] = '\0';
				}

				/* If the value ends with just ".", remove the dot */
				if (val[strlen(val) - 1] == '.')
					val[strlen(val) - 1] = '\0';
				break;

			case FTString:
			case FTLogical:
			case FTDate:
				rv = snprintf(val, MAXVALUELEN, "%s", DBFReadStringAttribute(state->hDBFHandle, item, i));
				if (rv >= MAXVALUELEN || rv == -1)
				{
					stringbuffer_aprintf(sbwarn, "Warning: field %d name truncated\n", i);
					val[MAXVALUELEN - 1] = '\0';
				}
				break;

			default:
				snprintf(state->message, SHPLOADERMSGLEN, _("Error: field %d has invalid or unknown field type (%d)"), i, state->types[i]);

				SHPDestroyObject(obj);
				stringbuffer_destroy(sbwarn);
				stringbuffer_destroy(sb);

				return SHPLOADERERR;
			}

			if (state->config->encoding)
			{
				char *encoding_msg = _("Try \"LATIN1\" (Western European), or one of the values described at http://www.postgresql.org/docs/current/static/multibyte.html.");

				rv = utf8(state->config->encoding, val, &utf8str);

				if (rv != UTF8_GOOD_RESULT)
				{
					if ( rv == UTF8_BAD_RESULT )
						snprintf(state->message, SHPLOADERMSGLEN, _("Unable to convert data value \"%s\" to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s"), utf8str, strerror(errno), state->config->encoding, encoding_msg);
					else if ( rv == UTF8_NO_RESULT )
						snprintf(state->message, SHPLOADERMSGLEN, _("Unable to convert data value to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s"), strerror(errno), state->config->encoding, encoding_msg);
					else
						snprintf(state->message, SHPLOADERMSGLEN, _("Unexpected return value from utf8()"));

					if ( rv == UTF8_BAD_RESULT )
						free(utf8str);

					return SHPLOADERERR;
				}
				strncpy(val, utf8str, MAXVALUELEN);
				free(utf8str);

			}

			/* Escape attribute correctly according to dump format */
			if (state->config->dump_format)
			{
				escval = escape_copy_string(val);
				stringbuffer_aprintf(sb, "%s", escval);
			}
			else
			{
				escval = escape_insert_string(val);
				stringbuffer_aprintf(sb, "'%s'", escval);
			}

			/* Free the escaped version if required */
			if (val != escval)
				free(escval);
		}

		/* Only put in delimeter if not last field or a shape will follow */
		if (state->config->readshape == 1 || i < DBFGetFieldCount(state->hDBFHandle) - 1)
		{
			if (state->config->dump_format)
				stringbuffer_aprintf(sb, "\t");
			else
				stringbuffer_aprintf(sb, ",");
		}

		/* End of DBF attribute loop */
	}


	/* Add the shape attribute if we are reading it */
	if (state->config->readshape == 1)
	{
		/* Handle the case of a NULL shape */
		if (obj->nVertices == 0)
		{
			if (state->config->dump_format)
				stringbuffer_aprintf(sb, "\\N");
			else
				stringbuffer_aprintf(sb, "NULL");
		}
		else
		{
			/* Handle all other shape attributes */
			switch (obj->nSHPType)
			{
			case SHPT_POLYGON:
			case SHPT_POLYGONM:
			case SHPT_POLYGONZ:
				res = GeneratePolygonGeometry(state, obj, &geometry);
				break;

			case SHPT_POINT:
			case SHPT_POINTM:
			case SHPT_POINTZ:
				res = GeneratePointGeometry(state, obj, &geometry, 0);
				break;

			case SHPT_MULTIPOINT:
			case SHPT_MULTIPOINTM:
			case SHPT_MULTIPOINTZ:
				/* Force it to multi unless using -S */
				res = GeneratePointGeometry(state, obj, &geometry,
					state->config->simple_geometries ? 0 : 1);
				break;

			case SHPT_ARC:
			case SHPT_ARCM:
			case SHPT_ARCZ:
				res = GenerateLineStringGeometry(state, obj, &geometry);
				break;

			default:
				snprintf(state->message, SHPLOADERMSGLEN, _("Shape type is not supported, type id = %d"), obj->nSHPType);
				SHPDestroyObject(obj);
				stringbuffer_destroy(sbwarn);
				stringbuffer_destroy(sb);

				return SHPLOADERERR;
			}
			/* The default returns out of the function, so res will always have been set. */
			if (res != SHPLOADEROK)
			{
				/* Error message has already been set */
				SHPDestroyObject(obj);
				stringbuffer_destroy(sbwarn);
				stringbuffer_destroy(sb);

				return SHPLOADERERR;
			}

			/* Now generate the geometry string according to the current configuration */
			if (!state->config->dump_format)
			{
				if (state->to_srid != state->from_srid)
				{
					stringbuffer_aprintf(sb, "ST_Transform(");
				}
				stringbuffer_aprintf(sb, "'");
			}

			stringbuffer_aprintf(sb, "%s", geometry);

			if (!state->config->dump_format)
			{
				stringbuffer_aprintf(sb, "'");

				/* Close the ST_Transform if reprojecting. */
				if (state->to_srid != state->from_srid)
				{
					/* We need to add an explicit cast to geography/geometry to ensure that
					   PostgreSQL doesn't get confused with the ST_Transform() raster
					   function. */
					if (state->config->geography)
						stringbuffer_aprintf(sb, "::geometry, %d)::geography", state->to_srid);
					else
						stringbuffer_aprintf(sb, "::geometry, %d)", state->to_srid);
				}
			}

			free(geometry);
		}

		/* Tidy up everything */
		SHPDestroyObject(obj);
	}

	/* Close the line correctly for dump/insert format */
	if (!state->config->dump_format)
		stringbuffer_aprintf(sb, ");");


	/* Copy the string buffer into a new string, destroying the string buffer */
	ret = (char *)malloc(strlen((char *)stringbuffer_getstring(sb)) + 1);
	strcpy(ret, (char *)stringbuffer_getstring(sb));
	stringbuffer_destroy(sb);

	*strrecord = ret;

	/* If any warnings occurred, set the returned message string and warning status */
	if (strlen((char *)stringbuffer_getstring(sbwarn)) > 0)
	{
		snprintf(state->message, SHPLOADERMSGLEN, "%s", stringbuffer_getstring(sbwarn));
		stringbuffer_destroy(sbwarn);

		return SHPLOADERWARN;
	}
	else
	{
		/* Everything went okay */
		stringbuffer_destroy(sbwarn);

		return SHPLOADEROK;
	}
}