/* * Local function prototypes */ static int _calc_shapelen ( GeomType type, int numpoints, int numparts ); static void _get_extrema ( int num_points, Point *pt, double *z, double *m, double *xy_bnd, double *z_bnd, double *m_bnd ); static int _get_shp_parts ( char *cp, int swap_bytes, Geometry *geom ); static int _get_shp_multipoint ( char *cp, int swap_bytes, Geometry *geom ); static int _get_shp_point ( char *cp, int swap_bytes, Geometry *geom ); /*************************************************************************** * * geom_to_shape - takes a geometry and converts it into a shape * representation. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * Converts a geometry into its ESRI shape representation. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * geom == (Geometry *) The geometry object * max_alloced == (int *) The maximum number of bytes * allocated to the binary array. * data_len == (int *) The number of bytes in the shape. * binary == (char **) The shape binary. * * RETURN == (void) * ****************************************************************************/ void geom_to_shape ( Geometry *geom, int *max_alloced, int *data_len, char **binary ) { char *cp; double xy_bnd[4]; double z_bnd[2]; double m_bnd[2]; int i; int swap; int npoints = geom->num_points; int nparts = geom->num_parts; Point *pt = geom->pt; double *m = geom->m; double *z = geom->z; ShpType type; ENDIAN_TEST (i); /* Sets i = 0 if big-endian, 1 if little-endian */ swap = 1 - i; /* Calculate data_len. */ *data_len = _calc_shapelen (geom->type, npoints, nparts); /* Allocate memory to the binary character array, set max_alloced equal to data_len if this is the first call to put_shape. Otherwise, if the data_len is larger then max_alloced, reallocate the larger data_len to the binary character array. */ if (*max_alloced == 0) { *binary = (char *)malloc (*data_len); *max_alloced = *data_len; } else if (*max_alloced < *data_len) { *binary = (char *) realloc (*binary, *data_len); *max_alloced = *data_len; } /* Copy the address of the binary character array to the character pointer cp. */ cp = *binary; /* The put_integer function byte swaps an integer value if necessary, and advances the cp character pointer after the interger value just added. The put_xy and put_double functions operate in the same manner as put_integer does, except they add an array of double precision numbers. */ switch (geom->type) { case geomEmpty: /* Geometry is empty so the buffer only contains its datatype */ type = shpNil; put_integer (&cp, swap, 1, (int *)&type); break; case geomPoint: /* Point */ type = shpPoint; put_integer (&cp, swap, 1, (int *)&type); put_xy (&cp, swap, 1, pt); /* Add the X, Y coordinate */ break; case geomPointM: /* Point with measure */ type = shpPointM; put_integer (&cp, swap, 1, (int *)&type); put_xy (&cp, swap, 1, pt); /* Add the X, Y coordinate */ put_double (&cp, swap, 1, m); /* Add the measure */ break; case geomPointZ: /* Point with Z coordinate */ type = shpPointZ; put_integer (&cp, swap, 1, (int *)&type); put_xy (&cp, swap, 1, pt); /* Add the X, Y coordinate */ put_double (&cp, swap, 1, z); /* Add the Z coordinate */ break; case geomPointZM: /* Point with Z coordinate and measure. */ type = shpPointZM; put_integer (&cp, swap, 1, (int *)&type); put_xy (&cp, swap, 1, pt); /* Add the X, Y coordinate */ put_double (&cp, swap, 1, z); /* Add the Z coordinate */ put_double (&cp, swap, 1, m); /* Add the measure */ break; case geomMultiPoint: /* Multipoint. */ type = shpMultiPoint; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ put_xy (&cp, swap, npoints, pt); /* Add the X, Y coords */ break; case geomMultiPointM: /* Multipoint with measure. */ type = shpMultiPointM; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y and measures */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ put_xy (&cp, swap, npoints, pt); /* Add the X, Y coords */ put_double (&cp, swap, 2, m_bnd); /* Add the extreme measures */ put_double (&cp, swap, npoints, m); /* Add the measures */ break; case geomMultiPointZ: /* Multipoint with Z ordinates */ type = shpMultiPointZ; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y, Z and measures. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ put_xy (&cp, swap, npoints, pt); /* Add the X, Y coordinates */ put_double (&cp, swap, 2, z_bnd); /* Add the Z extrema */ put_double (&cp, swap, npoints, z); /* Add the Z ordinates */ break; case geomMultiPointZM: /* Multipoint with Z ordinates and measures */ type = shpMultiPointZM; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y, Z and measures. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ put_xy (&cp, swap, npoints, pt); /* Add the X, Y coords */ put_double (&cp, swap, 2, z_bnd); /* Add the Z extreme */ put_double (&cp, swap, npoints, z); /* Add the Z ordinates */ put_double (&cp, swap, 2, m_bnd); /* Add the extreme measures */ put_double (&cp, swap, npoints, m); /* Add the measures */ break; case geomLineString: case geomMultiLineString: type = shpPolyline; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &nparts); /* Add the no. of parts */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ if (nparts > 1) { /* There is more that one part; add the part offsets array */ put_integer (&cp, swap, nparts, geom->offsets); } else { /* There is only one part; set the part offsets array to 0. */ memset (cp, 0, sizeof (int)); cp += sizeof (int); /* Advance the character pointer cp */ } put_xy (&cp, swap, npoints, pt); /* Add the point array */ break; case geomLineStringM: case geomMultiLineStringM: type = shpPolylineM; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y and measures. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &nparts); /* Add the no. of parts */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ if (nparts > 1) { /* There is more that one part; add the part offsets array */ put_integer (&cp, swap, nparts, geom->offsets); } else { /* There is only one part; set the part offsets array to 0. */ memset (cp, 0, sizeof (int)); cp += sizeof (int); /* Advance the character pointer cp */ } put_xy (&cp, swap, npoints, pt); /* Add the points array */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ put_double (&cp, swap, 2, m_bnd); /* Add the measure extremes */ put_double (&cp, swap, npoints, m); /* Add the measures array */ break; case geomLineStringZ: case geomMultiLineStringZ: type = shpPolylineZ; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y, Z and measures. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &nparts); /* Add the no. of parts */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ if (nparts > 1) { /* There is more that one part; add the part offsets array */ put_integer (&cp, swap, nparts, geom->offsets); } else { /* There is only one part; set the part offsets array to 0. */ memset (cp, 0, sizeof (int)); cp += sizeof (int); /* Advance the character pointer cp */ } put_xy (&cp, swap, npoints, pt); /* Add the no. of points */ put_double (&cp, swap, 2, z_bnd); /* Add the Z extremes */ put_double (&cp, swap, npoints, z); /* Add the Z array */ break; case geomLineStringZM: case geomMultiLineStringZM: type = shpPolylineZM; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y, Z and measures. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &nparts); /* Add the no. of parts */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ if (nparts > 1) { /* There is more that one part; add the part offsets array */ put_integer (&cp, swap, nparts, geom->offsets); } else { /* There is only one part; set the part offsets array to 0. */ memset (cp, 0, sizeof (int)); cp += sizeof (int); /* Advance the character pointer cp */ } put_xy (&cp, swap, npoints, pt); /* Add the no. of points */ put_double (&cp, swap, 2, z_bnd); /* Add the Z extemes */ put_double (&cp, swap, npoints, z); /* Add the Z array */ put_double (&cp, swap, 2, m_bnd); /* Add the measure extremes */ put_double (&cp, swap, npoints, m); /* Add the measure array */ break; case geomPolygon: case geomMultiPolygon: type = shpPolygon; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &nparts); /* Add the no. of parts */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ if (nparts > 1) { /* There is more that one part; add the part offsets array */ put_integer (&cp, swap, nparts, geom->offsets); } else { /* There is only one part; set the part offsets array to 0. */ memset (cp, 0, sizeof (int)); cp += sizeof (int); /* Advance the character pointer cp */ } put_xy (&cp, swap, npoints, pt); /* Add the point array */ break; case geomPolygonM: case geomMultiPolygonM: type = shpPolygonM; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y and measures. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &nparts); /* Add the no. of parts */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ if (nparts > 1) { /* There is more that one part; add the part offsets array */ put_integer (&cp, swap, nparts, geom->offsets); } else { /* There is only one part; set the part offsets array to 0. */ memset (cp, 0, sizeof (int)); cp += sizeof (int); /* Advance the character pointer cp */ } put_xy (&cp, swap, npoints, pt); /* Add the points array */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ put_double (&cp, swap, 2, m_bnd); /* Add the measure extremes */ put_double (&cp, swap, npoints, m); /* Add the measures array */ break; case geomPolygonZ: case geomMultiPolygonZ: type = shpPolygonZ; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y, Z and measures. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &nparts); /* Add the no. of parts */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ if (nparts > 1) { /* There is more that one part; add the part offsets array */ put_integer (&cp, swap, nparts, geom->offsets); } else { /* There is only one part; set the part offsets array to 0. */ memset (cp, 0, sizeof (int)); cp += sizeof (int); /* Advance the character pointer cp */ } put_xy (&cp, swap, npoints, pt); /* Add the no. of points */ put_double (&cp, swap, 2, z_bnd); /* Add the Z extremes */ put_double (&cp, swap, npoints, z); /* Add the Z array */ break; case geomPolygonZM: case geomMultiPolygonZM: type = shpPolygonZM; put_integer (&cp, swap, 1, (int *)&type); /* Calculate the extreme X, Y, Z and measures. */ _get_extrema (npoints, pt, z, m, xy_bnd, z_bnd, m_bnd); put_double (&cp, swap, 4, xy_bnd); /* Add the X, Y extremes */ put_integer (&cp, swap, 1, &nparts); /* Add the no. of parts */ put_integer (&cp, swap, 1, &npoints); /* Add the no. of points */ if (nparts > 1) { /* There is more that one part; add the part offsets array */ put_integer (&cp, swap, nparts, geom->offsets); } else { /* There is only one part; set the part offsets array to 0. */ memset (cp, 0, sizeof (int)); cp += sizeof (int); /* Advance the character pointer cp */ } put_xy (&cp, swap, npoints, pt); /* Add the no. of points */ put_double (&cp, swap, 2, z_bnd); /* Add the Z extemes */ put_double (&cp, swap, npoints, z); /* Add the Z array */ put_double (&cp, swap, 2, m_bnd); /* Add the measure extremes */ put_double (&cp, swap, npoints, m); /* Add the measure array */ break; } } /*************************************************************************** * * _calc_shapelen - Calculates the number of bytes in the shape. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * Calculate the number of bytes in the shape. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * type == (GeomType) The geometry data type. * num_points == (int) The number of points in the geometry. * num_parts == (int) The number of parts into the geometry. * * RETURN == (void) * ****************************************************************************/ static int _calc_shapelen ( GeomType type, int numpoints, int numparts ) { int data_len; data_len = sizeof (int); /* Add the size of the data type */ switch (type) { case geomEmpty: /* Shape is empty. */ break; case geomPoint: /* Shape is a point. */ data_len += (2 * sizeof (double)); break; case geomPointZ: /* Shape is a point with a Z coordinate */ case geomPointM: /* Shape is a point with a measure. */ data_len += (3 * sizeof (double)); break; case geomPointZM: /* Shape is a point with a Z coordinate and a measure */ data_len += (4 * sizeof (double)); break; case geomMultiPoint: /* Shape is a multipoint. */ data_len += ((2 * numpoints) + 4) * sizeof(double) + sizeof (int); break; case geomMultiPointZ: /* Shape is a multipoint with Z coordinates. */ case geomMultiPointM: /* Shape is a multipoint with measures. */ data_len += ((3 * numpoints) + 6) * sizeof(double) + sizeof (int); break; case geomMultiPointZM: /* Shape is a multipoint with Z coords and measures */ data_len += ((4 * numpoints) + 8) * sizeof(double) + sizeof (int); break; case geomLineString: /* Shape is a polyline or polygon. */ case geomMultiLineString: case geomPolygon: case geomMultiPolygon: data_len += (2 + numparts) * sizeof (int); data_len += ((2 * numpoints) + 4) * sizeof(double); break; case geomLineStringM: /* Shape is a polyline or polygon with measures. */ case geomMultiLineStringM: case geomPolygonM: case geomMultiPolygonM: case geomLineStringZ: /* Shape is a polyline or polygon with Z coords. */ case geomMultiLineStringZ: case geomPolygonZ: case geomMultiPolygonZ: data_len += (2 + numparts) * sizeof (int); data_len += ((3 * numpoints) + 6) * sizeof(double); break; case geomLineStringZM: /* Shape is a polyline or polygon with */ case geomPolygonZM: /* Z coordinates and measures. */ case geomMultiLineStringZM: case geomMultiPolygonZM: data_len += (2 + numparts) * sizeof (int); data_len += ((4 * numpoints) + 8) * sizeof(double); break; } return data_len; } /*************************************************************************** * * _get_extrema - Calculates the extremes of the X, Y, Z and measures. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * Calculates the extremes of the X, Y, Z and measures. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * num_points == (int) The number of points in the geometry. * pt == (Point *) Array of X, Y coordinates. * z == (double *) Array of Z ordinates. * m == (double *) Array of measures. * xy_bnd == (double *) X, Y coordinate extremes. * z_bnd == (double *) Z ordinate extremes. * m_bnd == (double *) Measure extremes. * * RETURN == (void) * ****************************************************************************/ static void _get_extrema ( int num_points, Point *pt, double *z, double *m, double *xy_bnd, double *z_bnd, double *m_bnd ) { int i; /* Initialize the extremes */ xy_bnd[0] = xy_bnd[1] = DBL_MAX; /* min x, min y */ xy_bnd[2] = xy_bnd[3] = -DBL_MAX; /* max x, max y */ z_bnd[0] = m_bnd[0] = DBL_MAX; /* min z, min m */ z_bnd[1] = m_bnd[1] = -DBL_MAX; /* max z, max m */ for (i = 0; i < num_points; i++) { /* Find the min & max values */ if (pt[i].x < xy_bnd[0]) xy_bnd[0] = pt[i].x; if (pt[i].y < xy_bnd[1]) xy_bnd[1] = pt[i].y; if (pt[i].x > xy_bnd[2]) xy_bnd[2] = pt[i].x; if (pt[i].y > xy_bnd[3]) xy_bnd[3] = pt[i].y; if (z) { if (z[i] < z_bnd[0]) z_bnd[0] = z[i]; if (z[i] > z_bnd[1]) z_bnd[1] = z[i]; } if (m) { if (m[i] < m_bnd[0]) m_bnd[0] = m[i]; if (m[i] > m_bnd[1]) m_bnd[1] = m[i]; } } } /*************************************************************************** * * geom_to_shape - takes a geometry and converts it into a shape * representation. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * Converts a geometry into a shape. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * binary == (char **) The shape binary. * * RETURN == (int) Error code * ****************************************************************************/ int shape_to_geom ( char *binary, Geometry *geom ) { ShpType shape_type; int rc; char *cp; int swap_bytes; int i; ENDIAN_TEST (i); /* Sets i = 0 if big-endian, 1 if little-endian */ swap_bytes = 1 - i; cp = binary; get_integer (&cp, swap_bytes, 1, (int *) &shape_type); switch (shape_type) { /* copy the points based on shape type */ case shpNil: /* Nothing to do, we already made the shape nil */ break; case shpPoint: geom->type = geomPoint; rc = _get_shp_point (cp, swap_bytes, geom); break; case shpPointM: geom->type = geomPointM; rc = _get_shp_point (cp, swap_bytes, geom); break; case shpPointZ: geom->type = geomPointZ; rc = _get_shp_point (cp, swap_bytes, geom); break; case shpPointZM: geom->type = geomPointZM; rc = _get_shp_point (cp, swap_bytes, geom); break; case shpMultiPoint: geom->type = geomMultiPoint; rc = _get_shp_multipoint (cp, swap_bytes, geom); break; case shpMultiPointM: geom->type = geomMultiPoint; rc = _get_shp_multipoint (cp, swap_bytes, geom); break; case shpMultiPointZ: geom->type = geomMultiPointZ; rc = _get_shp_multipoint (cp, swap_bytes, geom); break; case shpMultiPointZM: geom->type = geomMultiPointZM; rc = _get_shp_multipoint (cp, swap_bytes, geom); break; case shpPolyline: geom->type = geomLineString; rc = _get_shp_parts (cp, swap_bytes, geom); break; case shpPolygon: geom->type = geomPolygon; rc = _get_shp_parts (cp, swap_bytes, geom); break; case shpPolylineM: geom->type = geomLineStringM; rc = _get_shp_parts (cp, swap_bytes, geom); break; case shpPolygonM: geom->type = geomPolygonM; rc = _get_shp_parts (cp, swap_bytes, geom); break; case shpPolylineZ: geom->type = geomLineStringZ; rc = _get_shp_parts (cp, swap_bytes, geom); break; case shpPolygonZ: geom->type = geomPolygonZ; rc = _get_shp_parts (cp, swap_bytes, geom); break; case shpPolylineZM: geom->type = geomLineStringZM; rc = _get_shp_parts (cp, swap_bytes, geom); break; case shpPolygonZM: geom->type = geomPolygonZM; rc = _get_shp_parts (cp, swap_bytes, geom); break; default: rc = GEOM_INVALID_SHP_TYPE; } return rc; } /*************************************************************************** * * _get_shp_parts - Extracts polygon or polyline parts from the * ESRI binary shape representation of a geometry. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * This function builds a polygon or polyline shape from the ESRI binary * shape representation of a geometry. Since it is a common routine for * lines and polygons, and the "multi" equivalents, it does not set * set the geometry, or verify the geometry. This is the caller's * responsibility. This function just fills in the numofpts, pt, zpt, * and mval fields. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * *A Parameters: * cp == (char *) a pointer into the binary buffer * swap_bytes == (int) 1 if bytes need to be swapped * geom == (Geometry *) The geometry object * * RETURN == (int) Error code * ****************************************************************************/ static int _get_shp_parts ( char *cp, int swap_bytes, Geometry *geom ) { int rc; int num_points; int num_parts; int has_m = geom->type & 0x01; int has_z = geom->type & 0x02; int prev_offset; int i; /* Skip over the double precision bounding box, we will calculate the envelope when needed */ cp += 4 * sizeof(double); /* Get the number of parts */ get_integer (&cp, swap_bytes, 1, &num_parts); if (num_parts <= 0) return GEOM_INVALID_NUM_PARTS; /* Get the total number of points */ get_integer (&cp, swap_bytes, 1, &num_points); if (num_points <= 0) return GEOM_TOO_FEW_POINTS; /* Allocate the parts offsets, then extract them */ if (geom->offsets != NULL) free (geom->offsets); geom->offsets = malloc (num_parts * sizeof(int)); if (NULL == geom->offsets) return GEOM_OUT_OF_MEMORY; get_integer (&cp, swap_bytes, num_parts, geom->offsets); /* make sure each part offset is legal */ prev_offset = 0; if (geom->offsets[0] != 0) return GEOM_INVALID_PART_OFFSET; for (i = 1; i < num_parts; i++) { if (geom->offsets[i] < prev_offset + 2) { /* Offsets should be monotonically increasing, and each part needs at least 2 points */ return GEOM_INVALID_PART_OFFSET; } prev_offset = geom->offsets[i]; } /* Check the last offset */ if (num_points < prev_offset + 2) return GEOM_INVALID_PART_OFFSET; /* Allocate space for the geometry points. */ rc = geom_allocate (geom, num_points); if (rc != GEOM_SUCCESS) return rc; geom->num_points = num_points; get_xy (&cp, swap_bytes, num_points, geom->pt); if (has_z) { cp += 2 * sizeof(double); /* Skip over Z extrema */ get_double (&cp, swap_bytes, num_points, geom->z); } if (has_m) { cp += 2 * sizeof(double); /* Skip over M extrema */ get_double (&cp, swap_bytes, num_points, geom->m); } return GEOM_SUCCESS; } /*************************************************************************** * * _get_shp_multipoint - Extracts a multipoint shape from the ESRI binary * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * This function builds a multipoint shape from the ESRI binary shape * representation of a geometry. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * cp == (char *) a pointer into the binary buffer * swap_bytes == (int) 1 if bytes need to be swapped * geom == (Geometry *) The geometry object * * RETURN == (int) Error code * ****************************************************************************/ static int _get_shp_multipoint ( char *cp, int swap_bytes, Geometry *geom ) { int rc; int num_points; int has_m = geom->type & 0x01; int has_z = geom->type & 0x02; /* Skip over the double precision bounding box, we will calculate the envelope when needed */ cp += 4 * sizeof(double); get_integer (&cp, swap_bytes, 1, &num_points); if (num_points <= 0) return GEOM_TOO_FEW_POINTS; /* Allocate space for the shape points. */ rc = geom_allocate(geom, num_points); if (rc != GEOM_SUCCESS) return rc; geom->num_points = num_points; /* Get an array of xy points */ get_xy (&cp, swap_bytes, num_points, geom->pt); if (has_z) { /* Skip over the double precision Z extrema */ cp += 2 * sizeof(double); /* Get the Z values */ get_double (&cp, swap_bytes, num_points, geom->z); } if (has_m) { /* Skip over the double precision M extrema */ cp += 2 * sizeof(double); /* Get the measure values */ get_double (&cp, swap_bytes, num_points, geom->m); } return GEOM_SUCCESS; } /*************************************************************************** * * _get_shp_point - Extracts a point shape from the ESRI binary * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: * This function builds a point shape from the ESRI binary shape * representation of a shape. * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: * swap_bytes == (int) 1 if bytes need to be swapped * cp == (char *) a pointer into the binary buffer * geom == (Geometry *) The geometry object * * RETURN == (int) Error code * ****************************************************************************/ static int _get_shp_point ( char *cp, int swap_bytes, Geometry *geom ) { int rc; int has_m = geom->type & 0x01; int has_z = geom->type & 0x02; /* Allocate space for the shape point */ rc = geom_allocate(geom, 1); if (rc != GEOM_SUCCESS) return rc; geom->num_points = 1; /* Get a single xy point, followed by the Z and/or M values */ get_xy (&cp, swap_bytes, 1, geom->pt); if (has_z) get_double (&cp, swap_bytes, 1, geom->z); if (has_m) get_double (&cp, swap_bytes, 1, geom->m); return GEOM_SUCCESS; }