You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
341 lines
0 B
341 lines
0 B
6 years ago
|
/******************************************************************************
|
||
|
* Copyright (c) 1999, Carl Anderson
|
||
|
*
|
||
|
* This code is based in part on the earlier work of Frank Warmerdam
|
||
|
*
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||
|
* copy of this software and associated documentation files (the "Software"),
|
||
|
* to deal in the Software without restriction, including without limitation
|
||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||
|
* Software is furnished to do so, subject to the following conditions:
|
||
|
*
|
||
|
* The above copyright notice and this permission notice shall be included
|
||
|
* in all copies or substantial portions of the Software.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||
|
* DEALINGS IN THE SOFTWARE.
|
||
|
******************************************************************************
|
||
|
*
|
||
|
* shp2dxf.c
|
||
|
*
|
||
|
* derived from a ESRI Avenue Script
|
||
|
* and DXF specification from AutoCad 3 (yes 1984)
|
||
|
*
|
||
|
* modifications Carl Andrson 11/96
|
||
|
* modifications Carl Andrson 3/97
|
||
|
*
|
||
|
* converted to C code 12/98
|
||
|
*
|
||
|
* requires shapelib 1.2
|
||
|
* gcc shpdxf.c shpopen.o dbfopen.o -o shpdxf
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include "shapefil.h"
|
||
|
|
||
|
#define FLOAT_PREC "%16.5f\r\n"
|
||
|
|
||
|
void dxf_hdr (x1,y1,x2,y2,df)
|
||
|
double x1,y1,x2,y2;
|
||
|
FILE *df;
|
||
|
{
|
||
|
/* Create HEADER section */
|
||
|
|
||
|
fprintf( df, " 0\r\n");
|
||
|
fprintf( df, "SECTION\r\n");
|
||
|
fprintf( df, " 2\r\n" );
|
||
|
fprintf( df, "HEADER\r\n" );
|
||
|
fprintf( df, " 9\r\n" );
|
||
|
fprintf( df, "$EXTMAX\r\n" );
|
||
|
fprintf( df, " 10\r\n" );
|
||
|
fprintf( df, FLOAT_PREC, x2 );
|
||
|
fprintf( df, " 20\r\n" );
|
||
|
fprintf( df, FLOAT_PREC, y2 );
|
||
|
fprintf( df, " 9\r\n" );
|
||
|
fprintf( df, "$EXTMIN\r\n" );
|
||
|
fprintf( df, " 10\r\n" );
|
||
|
fprintf( df, FLOAT_PREC, x1 );
|
||
|
fprintf( df, " 20\r\n" );
|
||
|
fprintf( df, FLOAT_PREC, y1 );
|
||
|
fprintf( df, " 9\r\n" );
|
||
|
fprintf( df, "$LUPREC\r\n" );
|
||
|
fprintf( df, " 70\r\n" );
|
||
|
fprintf( df, " 14\r\n" );
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "ENDSEC\r\n" );
|
||
|
|
||
|
/* ' Create TABLES section */
|
||
|
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "SECTION\r\n" );
|
||
|
fprintf( df, " 2\r\n" );
|
||
|
fprintf( df, "TABLES\r\n" );
|
||
|
/* ' Table 1 - set up line type */
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "TABLE\r\n" );
|
||
|
fprintf( df, " 2\r\n" );
|
||
|
fprintf( df, "LTYPE\r\n" );
|
||
|
fprintf( df, " 70\r\n" );
|
||
|
fprintf( df, "2\r\n" );
|
||
|
/* ' Entry 1 of Table 1 */
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "LTYPE\r\n" );
|
||
|
fprintf( df, " 2\r\n" );
|
||
|
fprintf( df, "CONTINUOUS\r\n" );
|
||
|
fprintf( df, " 70\r\n" );
|
||
|
fprintf( df, "64\r\n" );
|
||
|
fprintf( df, " 3\r\n" );
|
||
|
fprintf( df, "Solid line\r\n" );
|
||
|
fprintf( df, " 72\r\n" );
|
||
|
fprintf( df, "65\r\n" );
|
||
|
fprintf( df, " 73\r\n" );
|
||
|
fprintf( df, "0\r\n" );
|
||
|
fprintf( df, " 40\r\n" );
|
||
|
fprintf( df, "0.0\r\n" );
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "ENDTAB\r\n" );
|
||
|
/* End of TABLES section */
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "ENDSEC\r\n" );
|
||
|
|
||
|
/* Create BLOCKS section */
|
||
|
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "SECTION\r\n" );
|
||
|
fprintf( df, " 2\r\n" );
|
||
|
fprintf( df, "BLOCKS\r\n" );
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "ENDSEC\r\n" );
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
fprintf( df, "SECTION\r\n" );
|
||
|
fprintf( df, " 2\r\n" );
|
||
|
fprintf( df, "ENTITIES\r\n" );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
dxf_ent_preamble (dxf_type, id, df)
|
||
|
int dxf_type;
|
||
|
char *id;
|
||
|
FILE *df;
|
||
|
{
|
||
|
|
||
|
fprintf( df, " 0\r\n" );
|
||
|
|
||
|
switch (dxf_type) {
|
||
|
case SHPT_POLYGON:
|
||
|
case SHPT_ARC: fprintf (df, "POLYLINE\r\n");
|
||
|
break;
|
||
|
default: fprintf(df, "POINT\r\n");
|
||
|
}
|
||
|
|
||
|
fprintf( df, " 8\r\n");
|
||
|
fprintf( df, "%s\r\n", id );
|
||
|
switch ( dxf_type ) {
|
||
|
case SHPT_ARC:
|
||
|
fprintf( df, " 6\r\n" );
|
||
|
fprintf( df, "CONTINUOUS\r\n" );
|
||
|
fprintf( df, " 66\r\n" );
|
||
|
fprintf( df, "1\r\n" );
|
||
|
break;
|
||
|
case SHPT_POLYGON:
|
||
|
fprintf( df, " 6\r\n" );
|
||
|
fprintf( df, "CONTINUOUS\r\n" );
|
||
|
fprintf( df, " 66\r\n" );
|
||
|
fprintf( df, "1\r\n" );
|
||
|
fprintf( df, " 70\r\n");
|
||
|
fprintf (df, "1\r\n");
|
||
|
default: break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
dxf_ent (id, x, y, z, dxf_type, df)
|
||
|
char *id;
|
||
|
double x,y,z;
|
||
|
int dxf_type;
|
||
|
FILE *df;
|
||
|
{
|
||
|
if ((dxf_type == SHPT_ARC) || ( dxf_type == SHPT_POLYGON)) {
|
||
|
fprintf( df, " 0\r\n");
|
||
|
fprintf( df, "VERTEX\r\n");
|
||
|
fprintf( df, " 8\r\n");
|
||
|
fprintf( df, "%s\r\n", id);
|
||
|
}
|
||
|
fprintf( df, " 10\r\n" );
|
||
|
fprintf( df, FLOAT_PREC, x );
|
||
|
fprintf( df, " 20\r\n" );
|
||
|
fprintf( df, FLOAT_PREC, y );
|
||
|
fprintf( df, " 30\r\n" );
|
||
|
if ( z != 0 )
|
||
|
fprintf( df, FLOAT_PREC, z );
|
||
|
else
|
||
|
fprintf( df, "0.0\r\n" );
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
dxf_ent_postamble (dxf_type, df)
|
||
|
int dxf_type;
|
||
|
FILE *df;
|
||
|
{
|
||
|
if ((dxf_type == SHPT_ARC) || ( dxf_type == SHPT_POLYGON))
|
||
|
fprintf( df, " 0\r\nSEQEND\r\n 8\r\n0\r\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
main (int argc, char **argv)
|
||
|
|
||
|
{
|
||
|
char shpFileName[80] = "", dbfFileName[80] = "";
|
||
|
char dxfFileName[80] = "";
|
||
|
char idfldName[15];
|
||
|
char zfldName[6] = "ELEV";
|
||
|
char fldName[15];
|
||
|
char id[255];
|
||
|
double elev;
|
||
|
int parts, *panParts, nParts, nVertices;
|
||
|
FILE *dxf;
|
||
|
SHPHandle shp;
|
||
|
DBFHandle dbf;
|
||
|
DBFFieldType idfld_type;
|
||
|
double adfBoundsMin[4], adfBoundsMax[4];
|
||
|
int vrtx, shp_type, shp_numrec, zfld, idfld, nflds, recNum, part;
|
||
|
unsigned int MaxElem = -1;
|
||
|
|
||
|
if ( argc < 2 ) {
|
||
|
printf ("usage: shpdxf shapefile {idfield}\r\n");
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
strcpy (shpFileName,argv[1]);
|
||
|
strncpy (dbfFileName, shpFileName, strlen(shpFileName)-3);
|
||
|
strcat (dbfFileName,"dbf");
|
||
|
|
||
|
strncpy (dxfFileName, shpFileName,strlen(shpFileName)-3);
|
||
|
strcat( dxfFileName, "dxf");
|
||
|
|
||
|
shp = SHPOpen (shpFileName, "rb");
|
||
|
dbf = DBFOpen (dbfFileName, "rb");
|
||
|
dxf = fopen( dxfFileName, "w");
|
||
|
|
||
|
printf("Starting conversion %s(%s) -> %s\r\n",
|
||
|
shpFileName,dbfFileName,dxfFileName);
|
||
|
|
||
|
SHPGetInfo (shp, &shp_numrec, &shp_type, adfBoundsMin, adfBoundsMax );
|
||
|
printf ("file has %d objects\r\n", shp_numrec);
|
||
|
dxf_hdr(adfBoundsMin[0], adfBoundsMin[1], adfBoundsMax[0], adfBoundsMax[1],
|
||
|
dxf);
|
||
|
|
||
|
/* Before proceeding, allow the user to specify the ID field to use or default to the record number.... */
|
||
|
|
||
|
if ( argc > 3 ) MaxElem = atoi(argv[3]);
|
||
|
|
||
|
nflds = DBFGetFieldCount(dbf);
|
||
|
if ( argc > 2 ) {
|
||
|
strcpy (idfldName, argv[2]);
|
||
|
for ( idfld=0; idfld < nflds; idfld++ ) {
|
||
|
idfld_type = DBFGetFieldInfo( dbf, idfld, fldName, NULL, NULL);
|
||
|
if (!strcmp (idfldName, fldName ))
|
||
|
break;
|
||
|
}
|
||
|
if ( idfld >= nflds ) {
|
||
|
printf ("Id field %s not found, using default\r\n",idfldName);
|
||
|
idfld = -1;
|
||
|
} else
|
||
|
printf ("proceeding with field %s for LayerNames\r\n",fldName);
|
||
|
}
|
||
|
else
|
||
|
idfld = -1;
|
||
|
|
||
|
for ( zfld=0; zfld < nflds; zfld++ ) {
|
||
|
DBFGetFieldInfo( dbf, zfld, fldName, NULL, NULL);
|
||
|
if (!strcmp (zfldName, fldName ))
|
||
|
break;
|
||
|
}
|
||
|
if ( zfld >= nflds )
|
||
|
zfld = -1;
|
||
|
// printf ("proceeding with id = %d, elevation = %d\r\n",idfld, zfld);
|
||
|
|
||
|
/* Proceed to process data..... */
|
||
|
|
||
|
for ( recNum = 0; (recNum < shp_numrec) && (recNum < MaxElem); recNum++) {
|
||
|
|
||
|
SHPObject *shape;
|
||
|
|
||
|
if ( idfld >= 0 )
|
||
|
switch (idfld_type) {
|
||
|
case FTString: sprintf (id, "lvl_%s",DBFReadStringAttribute ( dbf, recNum, idfld ));
|
||
|
break;
|
||
|
default: sprintf(id, "%-20.0lf", DBFReadDoubleAttribute (dbf, recNum, idfld));
|
||
|
}
|
||
|
else
|
||
|
sprintf (id,"lvl_%-20d",(recNum +1 ));
|
||
|
|
||
|
|
||
|
if ( zfld >= 0 )
|
||
|
elev = 0;
|
||
|
else
|
||
|
elev = DBFReadDoubleAttribute ( dbf, recNum, zfld );
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
printf("\r\nworking on obj %d", recNum);
|
||
|
#endif
|
||
|
|
||
|
shape = SHPReadObject( shp, recNum );
|
||
|
|
||
|
nVertices = shape->nVertices;
|
||
|
nParts = shape->nParts;
|
||
|
panParts = shape->panPartStart;
|
||
|
part = 0;
|
||
|
for (vrtx=0; vrtx < nVertices; vrtx ++ ) {
|
||
|
#ifdef DEBUG
|
||
|
printf("\rworking on part %d, vertex %d", part,vrtx);
|
||
|
#endif
|
||
|
if ( panParts[part] == vrtx ) {
|
||
|
#ifdef DEBUG
|
||
|
printf ("object preamble\r\n");
|
||
|
#endif
|
||
|
dxf_ent_preamble (shp_type, id, dxf);
|
||
|
}
|
||
|
|
||
|
dxf_ent (id, shape->padfX[vrtx], shape->padfY[vrtx],
|
||
|
elev, shp_type, dxf);
|
||
|
|
||
|
if ((panParts[part] == (vrtx + 1))|| (vrtx == (nVertices -1)) ) {
|
||
|
dxf_ent_postamble (shp_type, dxf);
|
||
|
part ++;
|
||
|
}
|
||
|
}
|
||
|
SHPDestroyObject( shape );
|
||
|
}
|
||
|
|
||
|
/* close out DXF file */
|
||
|
fprintf( dxf, "0\r\n" );
|
||
|
fprintf( dxf, "ENDSEC\r\n" );
|
||
|
fprintf( dxf, "0\r\n" );
|
||
|
fprintf( dxf, "EOF\r\n" );
|
||
|
|
||
|
|
||
|
SHPClose (shp);
|
||
|
DBFClose (dbf);
|
||
|
fclose (dxf);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|