/* Delete shapes of insufficient size from shapefile */ /* gcc shpchop.c libdbf.c dbfopen.c shpopen.c -lm */ #include #include #include "shapefil.h" #include "libdbf.h" /* My own DBF functions */ /* Function for getting length of pline */ double shpLen(SHPObject* s){ double d = 0.0; if(s != NULL){ int i, fin; double thisX, thisY, xOff, yOff; double lastX = s->padfX[0]; double lastY = s->padfY[0]; for(i=1, fin=s->nVertices; ipadfX[i]; thisY = s->padfY[i]; xOff = thisX - lastX; yOff = thisY - lastY; if(thisX != 0.0 && thisY != 0.0){ d += sqrt(xOff * xOff + yOff * yOff); } else { /* Either X or Y is 0, no need for trig */ xOff = fabs(xOff); yOff = fabs(yOff); d += xOff + yOff; } lastX = thisX; lastY = thisY; } } return d; } /* Main function*/ int main(int argc, char** argv){ char * shpName, *ofName; double cutoffLen = 0.0; /* Minimum length of shape */ SHPHandle inSHP = NULL, outSHP = NULL; DBFHandle inDBF = NULL, outDBF = NULL; SHPObject *mySHP; DBFRecord *myDBF; int i=0,j=0; /* in/out indexes */ /* Take input */ if(argc < 2){ /* TODO: Real error message */ fprintf(stderr, "FATAL: Not enough args.\n"); exit(0); } else { /* TODO: Real input handling */ char * myArg; double myD; while(--argc > 0){ myArg = argv[argc]; /* Use outSHP as generic (SHPObject*) */ if(inSHP == NULL && (outSHP = SHPOpen(myArg, "rb")) != NULL){ /* File found, keep inSHP */ shpName = myArg; inDBF = DBFOpen(myArg, "rb"); inSHP = outSHP; outSHP = NULL; /* reset outSHP */ /* NOTE: atof is buggy in Cygwin */ } else if( (myD = atof(myArg)) > 0.0){ if(isnan(myD)){ fprintf(stderr, "NOTE: %s is NaN\n",myArg); } else { fprintf(stderr, "NOTE: Using length %f\n",myD); cutoffLen = myD; } } else { fprintf(stderr, "WARN: Arg %s neither double nor shapefile\n",myArg); } } } /* Check input */ if(inDBF == NULL || inSHP == NULL){ fprintf(stderr, "FATAL: Could not open SHP and DBF\n"); exit(0); } if(cutoffLen <= 0.0){ fprintf(stderr, "FATAL: No input \n"); exit(0); } /* Create new shpfile and dbf*/ ofName = (char*)malloc(sizeof(char) * (strlen(shpName) + 8)); strcpy(ofName, shpName); strcat(ofName, "trimmed"); outDBF = DBFCreate(ofName); outSHP = SHPCreate(ofName, inSHP->nShapeType); DBFCopyFields(outDBF, inDBF); /* Check each shape's length */ while((mySHP = SHPReadObject(inSHP, i)) != NULL){ double myLen = shpLen(mySHP); if(myLen > cutoffLen){ myDBF = DBFGetRecord(inDBF,i); /* Copy shp and dbf */ /* Use -1 for append for shapes */ SHPWriteObject(outSHP, -1, mySHP); DBFWriteRecord(outDBF, j, myDBF); j++; DBFRecordFree(myDBF); } else { /* debug: fprintf(stderr, "%f <= %f\n",myLen, cutoffLen); */ } i++; SHPDestroyObject(mySHP); /* Dealloc */ } /* Write new shpfile and dbf */ DBFClose(inDBF); DBFClose(outDBF); SHPClose(inSHP); SHPClose(outSHP); }