gen2shp.c
来自「由arcgis的general产生的数据转换成shape文件格式」· C语言 代码 · 共 523 行
C
523 行
/* * $Id: gen2shp.c,v 1.8 2000/06/12 13:23:35 jan Exp $ * * Copyright (C) 1999 by Jan-Oliver Wagner <jan@intevation.de> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <string.h>#include <libshp/shapefil.h>#include "utils.h"#define VERSION "0.3.0"#ifdef DEBUG#define DEBUG_OUT(str) fprintf(stderr, "gen2shp debug: " str)#define DEBUG_OUT1(str,v) fprintf(stderr, "gen2shp debug: " str, v)#define DEBUG_OUT2(str,v,w) fprintf(stderr, "gen2shp debug: " str, v, w)#define DEBUG_OUT3(str,v,w,x) fprintf(stderr, "gen2shp debug: " str, v, w, x)#else#define DEBUG_OUT(str) #define DEBUG_OUT1(str,v) #define DEBUG_OUT2(str,v,w) #define DEBUG_OUT3(str,v,w,x) #endif/* Error codes for exit() routine: */#define ERR_USAGE 1#define ERR_TYPE 2#define ERR_FORMAT 3#define ERR_OBJECTTYPE 4#define ERR_ALLOC 5#define ERR_DBFCREATE 10#define ERR_DBFADDFIELD 11#define ERR_DBFOPEN 12#define ERR_DBFWRITEINTEGERATTRIBUTE 13#define ERR_SHPOPEN 20/* Object Type codes used in main(): */#define OBJECTTYPE_NONE 0#define OBJECTTYPE_POINT 1#define OBJECTTYPE_LINE 2#define OBJECTTYPE_POLYGON 3/* minimum number of coordinates allocated blockwise */#define COORDS_BLOCKSIZE 100/* maximum length for read strings, * if input lines with more characters appear, * errors are likely to occur */#define STR_BUFFER_SIZE 300#ifdef USE_STRICMP#define CASE_INSENSITIVE_STR_CMP stricmp#else#define CASE_INSENSITIVE_STR_CMP strcasecmp#endifvoid print_version(FILE *file){ fprintf(file,"gen2shp version " VERSION "\n"); fprintf(file,"Copyright (C) 1999 by Jan-Oliver Wagner.\n" "The GNU GENERAL PUBLIC LICENSE applies. " "Absolutly No Warranty!\n");#ifdef DEBUG fprintf(file,"compiled with option: DEBUG\n"); #endif}static DBFHandle LaunchDbf ( const char *fname ) { DBFHandle hDBF; char dbffname[STR_BUFFER_SIZE]; char fieldname[STR_BUFFER_SIZE]; sprintf(dbffname, "%s.dbf", fname); sprintf(fieldname, "%s-id", fname); hDBF = DBFCreate( dbffname ); if( hDBF == NULL ) { fprintf(stderr, "DBFCreate(%s) failed.\n", fname ); exit(ERR_DBFCREATE); } if (DBFAddField( hDBF, fieldname, FTInteger, 11, 0 ) == -1) { fprintf(stderr, "DBFAddField(hDBF,%s,FTInteger,11,0) failed.\n", fieldname); exit(ERR_DBFADDFIELD); } DBFClose( hDBF ); hDBF = DBFOpen( dbffname, "r+b" ); if( hDBF == NULL ) { fprintf(stderr, "DBFOpen(%s,\"r+b\") failed.\n", dbffname ); exit(ERR_DBFOPEN); } return hDBF;}static SHPHandle LaunchShp( const char *fname, int ObjectType ) { SHPHandle hSHP; SHPObject *psShape; char shpfname[STR_BUFFER_SIZE]; sprintf(shpfname, "%s.shp", fname); switch (ObjectType) { case OBJECTTYPE_POINT: hSHP = SHPCreate( shpfname, SHPT_POINT ); break; case OBJECTTYPE_LINE: hSHP = SHPCreate( shpfname, SHPT_ARC ); break; case OBJECTTYPE_POLYGON: hSHP = SHPCreate( shpfname, SHPT_POLYGON ); break; default: fprintf(stderr, "internal error: " "unknown ObjectType=%d\n", ObjectType); exit(ERR_OBJECTTYPE); } if( hSHP == NULL ) { fprintf(stderr, "SHPOpen(%s, shape_type) failed.\n", shpfname ); exit(ERR_SHPOPEN); } return hSHP;}static void WriteDbf ( DBFHandle hDBF, int rec, int id ) { if (! DBFWriteIntegerAttribute(hDBF, rec, 0, id)) { fprintf(stderr, "DBFWriteIntegerAttribute(hDBFs,%d,1,%d) failed.\n", rec, id ); exit(ERR_DBFWRITEINTEGERATTRIBUTE); }}static void WritePoint( SHPHandle hSHP, int rec, double x, double y ) { SHPObject *psShape; psShape = SHPCreateObject( SHPT_POINT, rec, 0, NULL, NULL, 1, &x, &y, NULL, NULL ); SHPWriteObject( hSHP, -1, psShape ); SHPDestroyObject( psShape );}static void WriteLine( SHPHandle hSHP, int rec, int coords, double * x, double * y ) { SHPObject *psShape; psShape = SHPCreateObject( SHPT_ARC, rec, 0, NULL, NULL, coords, x, y, NULL, NULL ); SHPWriteObject( hSHP, -1, psShape ); SHPDestroyObject( psShape );}static void WritePolygon( SHPHandle hSHP, int rec, int coords, double * x, double * y, int nparts, int * partstarts) { SHPObject *psShape;DEBUG_OUT1("WritePolygon: rec = %d\n", rec);DEBUG_OUT1("WritePolygon: nparts = %d\n", nparts);DEBUG_OUT1("WritePolygon: coords = %d\n", coords); psShape = SHPCreateObject( SHPT_POLYGON, rec, nparts, partstarts, NULL, coords, x, y, NULL, NULL ); SHPWriteObject( hSHP, -1, psShape ); SHPDestroyObject( psShape );}/* read from fp and generate point shapefile to hDBF/hSHP */static void GeneratePoints ( FILE *fp, DBFHandle hDBF, SHPHandle hSHP ) { char linebuf[STR_BUFFER_SIZE]; /* buffer for line-wise reading from file */ int id; /* ID of point */ double x, y; /* coordinates of point */ char * str; /* tmp variable needed for assertions */ char * dstr; /* tmp variable needed to find out substrings */ int rec = 0; /* Counter for records */ while (getline(fp, linebuf) != EOF) { if (CASE_INSENSITIVE_STR_CMP(linebuf, "end") == 0) { DEBUG_OUT("'end' detected\n"); break; } if ((str = strtok(linebuf, " ,")) == NULL) { fprintf(stderr, "format error in line %d\n", rec + 1); exit(ERR_FORMAT); } id = atoi((const char *)str); if ((str = strtok(NULL, " ,")) == NULL) { fprintf(stderr, "format error in line %d\n", rec + 1); exit(ERR_FORMAT); } dstr = (char *)strchr((const char *)str, (char)'D'); if (dstr) *dstr = 'E'; x = atof((const char *)str); if ((str = strtok(NULL, " ,")) == NULL) { fprintf(stderr, "format error in line %d\n", rec + 1); exit(ERR_FORMAT); } dstr = (char *)strchr((const char *)str, (char)'D'); if (dstr) *dstr = 'E'; y = atof((const char *)str); DEBUG_OUT3("id=%d, x=%f, y=%f\n", id, x, y); WriteDbf(hDBF, rec, id); WritePoint(hSHP, rec, x, y); rec ++; }}/* read from fp and generate line/arc shapefile to hDBF/hSHP */static void GenerateLines ( FILE *fp, DBFHandle hDBF, SHPHandle hSHP ) { char linebuf[STR_BUFFER_SIZE]; /* buffer for line-wise reading from file */ int id; /* ID of point */ double * x = NULL, * y = NULL; /* coordinates arrays */ int vector_size = 0; /* current size of the vectors x and y */ char * str; /* tmp variable needed for assertions */ char * dstr; /* tmp variable needed to find out substrings */ int rec = 0; /* Counter for records */ int coord = 0; /* Counter for coordinates */ /* loop lines */ while (getline(fp, linebuf) != EOF) { if (CASE_INSENSITIVE_STR_CMP(linebuf, "end") == 0) { DEBUG_OUT("final 'end' detected\n"); break; } /* IDs are in single lines */ id = atoi((const char *)linebuf); DEBUG_OUT1("id=%d\n", id); coord = 0; /* loop coordinates of line 'id' */ while (getline(fp, linebuf) != EOF) { if (CASE_INSENSITIVE_STR_CMP(linebuf, "end") == 0) { DEBUG_OUT("a lines 'end' detected\n"); break; } /* allocate coordinate vectors if to small */ if (vector_size <= coord) { vector_size += COORDS_BLOCKSIZE; x = realloc(x, vector_size * sizeof(double)); y = realloc(y, vector_size * sizeof(double)); if (x == NULL || y == NULL) { fprintf(stderr, "memory allocation failed\n"); exit(ERR_ALLOC); } } if ((str = strtok(linebuf, " ,")) == NULL) { fprintf(stderr, "format error for line with " "id=%d\n", id); exit(ERR_FORMAT); } dstr = (char *)strchr((const char *)str, (char)'D'); if (dstr) *dstr = 'E'; x[coord] = atof((const char *)str); if ((str = strtok(NULL, " ,")) == NULL) { fprintf(stderr, "format error for line with " "id=%d\n", id); exit(ERR_FORMAT); } dstr = (char *)strchr((const char *)str, (char)'D'); if (dstr) *dstr = 'E'; y[coord] = atof((const char *)str); DEBUG_OUT2("x=%f, y=%f\n", x[coord], y[coord]); coord ++; } WriteDbf(hDBF, rec, id); WriteLine(hSHP, rec, coord, x, y); rec ++; } free(x); free(y);}/* read from fp and generate polgon shapefile to hDBF/hSHP */static void GeneratePolygons ( FILE *fp, DBFHandle hDBF, SHPHandle hSHP ) { char linebuf[STR_BUFFER_SIZE]; /* buffer for line-wise reading from file */ int id = -1; /* ID of polygon */ double * x = NULL, * y = NULL; /* coordinates arrays */ int vector_size = 0; /* current size of the vectors x and y */ int nparts = 0; /* number of parts */ int * partstarts = NULL; /* indices where new parts start in x[],y[] */ char * str; /* tmp variable needed for assertions */ char * dstr; /* tmp variable needed to find out substrings */ int rec = 0; /* Counter for records */ int coord = 0; /* Counter for coordinates */ /* loop polygons */ while (getline(fp, linebuf) != EOF) { if (CASE_INSENSITIVE_STR_CMP(linebuf, "end") == 0) { DEBUG_OUT("final 'end' detected\n"); break; } if (strchr(linebuf,',') == NULL) { /* we assume we found an id */ if (id != -1) { /* now its time to create the last read object */ WriteDbf(hDBF, rec, id); if (partstarts) partstarts[0] = 0; WritePolygon(hSHP, rec, coord, x, y, (nparts > 0 ? nparts+1 : 0), partstarts); free(partstarts); partstarts = NULL; rec ++; } /* IDs are on a single line */ id = atoi((const char *)linebuf); coord = 0; nparts = 0; DEBUG_OUT1("id=%d\n", id); } else { if (coord == 0) { DEBUG_OUT("no id for coordinates!"); exit(ERR_FORMAT); } nparts ++; /* a new part starts */ partstarts = realloc(partstarts, sizeof(int) * (nparts+1)); if (partstarts == NULL) { fprintf(stderr, "memory allocation failed\n"); exit(ERR_ALLOC); } partstarts[nparts] = coord; DEBUG_OUT1("newpart at %d\n", coord); /* the following block is just a copy from the while * construct below. Should find a more elegant solution! * --------- */ /* allocate coordinate vectors if to small */ if (vector_size <= coord) { vector_size += COORDS_BLOCKSIZE; x = realloc(x, vector_size * sizeof(double)); y = realloc(y, vector_size * sizeof(double)); if (x == NULL || y == NULL) { fprintf(stderr, "memory allocation failed\n"); exit(ERR_ALLOC); } } if ((str = strtok(linebuf, " ,")) == NULL) { fprintf(stderr, "format error for polygon with " "id=%d\n", id); exit(ERR_FORMAT); } dstr = (char *)strchr((const char *)str, (char)'D'); if (dstr) *dstr = 'E'; x[coord] = atof((const char *)str); if ((str = strtok(NULL, " ,")) == NULL) { fprintf(stderr, "format error for polygon with " "id=%d\n", id); exit(ERR_FORMAT); } dstr = (char *)strchr((const char *)str, (char)'D'); if (dstr) *dstr = 'E'; y[coord] = atof((const char *)str); DEBUG_OUT2("x=%f, y=%f\n", x[coord], y[coord]); coord ++; /* ---------- end of copy */ } /* loop coordinates of polygon 'id' */ while (getline(fp, linebuf) != EOF) { if (CASE_INSENSITIVE_STR_CMP(linebuf, "end") == 0) { DEBUG_OUT("an 'end' detected\n"); break; } /* allocate coordinate vectors if to small */ if (vector_size <= coord) { vector_size += COORDS_BLOCKSIZE; x = realloc(x, vector_size * sizeof(double)); y = realloc(y, vector_size * sizeof(double)); if (x == NULL || y == NULL) { fprintf(stderr, "memory allocation failed\n"); exit(ERR_ALLOC); } } if ((str = strtok(linebuf, " ,")) == NULL) { fprintf(stderr, "format error for polygon with " "id=%d\n", id); exit(ERR_FORMAT); } dstr = (char *)strchr((const char *)str, (char)'D'); if (dstr) *dstr = 'E'; x[coord] = atof((const char *)str); if ((str = strtok(NULL, " ,")) == NULL) { fprintf(stderr, "format error for polygon with " "id=%d\n", id); exit(ERR_FORMAT); } dstr = (char *)strchr((const char *)str, (char)'D'); if (dstr) *dstr = 'E'; y[coord] = atof((const char *)str); DEBUG_OUT2("x=%f, y=%f\n", x[coord], y[coord]); coord ++; } } /* now its time to create the last object */ WriteDbf(hDBF, rec, id); if (partstarts) partstarts[0] = 0; WritePolygon(hSHP, rec, coord, x, y, (nparts > 0 ? nparts+1 : 0), partstarts); free(partstarts); free(x); free(y);}int main( int argc, char ** argv ) { DBFHandle hDBF; /* handle for dBase file */ SHPHandle hSHP; /* handle for shape files .shx and .shp */ int ObjectType = OBJECTTYPE_NONE; if (argc != 3) { print_version(stderr); fprintf(stderr, "usage: %s outfile type < infile\n", argv[0]); fprintf(stderr, "\treads stdin and creates outfile.shp, " "outfile.shx and outfile.dbf\n" "\ttype must be one of these: points lines polygons\n" "\tinfile must be in 'generate' format\n"); exit(ERR_USAGE); } /* determine Object Type: */ if (strcmp(argv[2], "points") == 0) ObjectType = OBJECTTYPE_POINT; if (strcmp(argv[2], "lines") == 0) ObjectType = OBJECTTYPE_LINE; if (strcmp(argv[2], "polygons") == 0) ObjectType = OBJECTTYPE_POLYGON; if (ObjectType == OBJECTTYPE_NONE) { fprintf(stderr, "type '%s' unknown, use one of these: " "points lines polygons.", argv[2]); exit(ERR_TYPE); } DEBUG_OUT1("outfile=%s\n", argv[1]); DEBUG_OUT1("type=%s\n", argv[2]); /* Open and prepare output files */ hDBF = LaunchDbf(argv[1]); hSHP = LaunchShp(argv[1], ObjectType); /* Call generate function */ switch (ObjectType) { case OBJECTTYPE_POINT: GeneratePoints(stdin, hDBF, hSHP); break; case OBJECTTYPE_LINE: GenerateLines(stdin, hDBF, hSHP); break; case OBJECTTYPE_POLYGON: GeneratePolygons(stdin, hDBF, hSHP); break; default: fprintf(stderr, "internal error: " "unknown ObjectType=%d\n", ObjectType); exit(ERR_OBJECTTYPE); } /* Finish output files */ DBFClose( hDBF ); SHPClose( hSHP ); /* success */ exit(0);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?