static void bnd_npsa ( shp_record *onerec, char *header, char *subhdr, char *hdrnam, float *cenlat, float *cenlon, int *iret ) /************************************************************************ * bnd_npsa * * * * This function generates the predictive service areas boundaries * * bound header and sub-header lines. * * * * bnd_npsa ( onerec, header, subhdr, hdrnam, cenlat, cenlon, iret ) * * * * Input parameters: * * *onerec shp_record One shape record * * * * Output parameters: * * *header char Bound header line * * *subhdr char Bound sub-header line * * *hdrnam char Bound header name * * *cenlat float Center latitude * * *cenlon float Center longitude * * *iret int Return code * * 0 = Normal * * 1 = Incomplete record * ** * * Log: * * S. Jacobs/NCEP 4/10 Initial coding * * X. Guo/CWS 4/12 Increase variables(code) size * ***********************************************************************/ { /* * The array size is from the us state and territories * attributes specification. */ char code[20], name[81], gacc[81]; int iclat, iclon, nparts, ifld; float shplat, shplon; int len, ier; /*---------------------------------------------------------------------*/ *iret = 0; nparts = onerec->numprt; for ( ifld = 0; ifld < onerec->numfld; ifld++ ) { if ( strncmp ( onerec->fields[ifld].name, "NAT_CODE", strlen("NAT_CODE") ) == 0 ) { strcpy ( code, onerec->fields[ifld].data ); cst_lstr ( code, &len, &ier ); code[len] = '\0'; } else if ( strncmp ( onerec->fields[ifld].name, "PSA_NAME", strlen("PSA_NAME") ) == 0 ) { strcpy ( name, onerec->fields[ifld].data ); cst_lstr ( name, &len, &ier ); name[len] = '\0'; cst_rspc ( name, &ier ); } else if ( strncmp ( onerec->fields[ifld].name, "GACC", strlen("GACC") ) == 0 ) { strcpy ( gacc, onerec->fields[ifld].data ); cst_lstr ( gacc, &len, &ier ); gacc[len] = '\0'; cst_rspc ( gacc, &ier ); } } shp_gctr ( onerec, &shplon, &shplat, &ier ); iclat = (int)(ROUNDUP(shplat)*100.); iclon = (int)(ROUNDUP(shplon)*100.); *cenlat = shplat; *cenlon = shplon; sprintf ( header, "B%5.5d %-32.32s %5d %6d %3d", 0, name, iclat, iclon, nparts ); sprintf ( subhdr, "<AREA>%s<NAT_CODE>%s<GACC>%s", name, code, gacc ); sprintf ( hdrnam, "%s", name ); }
int main ( int argc, char *argv[] ) /************************************************************************ * main * * * * Main program of shpcv. * * * * int main(argc, argv) * * * * Input parameters: * * argc int number of parameters of command line * * **argv char parameter array of command line * * * * Output parameters: * * Return parameters: * * NONE * * * ** * * Log: * * R. Tian/SAIC 3/04 Initial coding * * R. Tian/SAIC 2/05 Modified shp_mtyp * * T. Piper/SAIC 01/06 Call ip_help if inputs incorrect * * H. Zeng/SAIC 07/07 added calling to shp_rdException() * * S. Jacobs/NCEP 3/11 Added debug_flag and print statements * * S. Jacobs/NCEP 6/14 Moved split func to after dump output * ***********************************************************************/ { dbf_header dbfhdr; shx_record shxrec; shp_record *reclst, *newrec, *currec; shp_part *curprt; char dbfnam[MAXSHP][LLPATH], shxnam[MAXSHP][LLPATH], shpnam[MAXSHP][LLPATH]; FILE *dbffp, *shxfp, *shpfp; long flen; int ifld, nf, opt, rec, prt, file_code, nbin, ier; float ratio, clat, clon; int lfld, dump, rdpt, cbnd, ctbl, pagflg; int numrec, numfil, ii; int mode, istat, iunit, itype; unsigned long shp_fips; char device[8], proj[8], filnam[20], prognm[6]; float xsize, ysize, angle1, angle2, angle3, lllat, lllon, urlat, urlon; Boolean exception_found; /*---------------------------------------------------------------------*/ lfld = G_FALSE; dump = G_FALSE; rdpt = G_FALSE; cbnd = G_FALSE; ctbl = G_FALSE; pagflg = G_FALSE; strcpy ( prognm, "shpcv" ); debug_flag = G_TRUE; /*=================== Parse command line arguments ====================*/ while ( ( opt = getopt ( argc, argv, "r:btldh" ) ) != -1 ) { switch ( opt ) { case 'r': /* reduce points ratio */ ratio = atof ( optarg ); if ( ratio <= 0.0 ) { ratio = 0.01; } rdpt = G_TRUE; break; case 'b': /* create bound and bound info */ cbnd = G_TRUE; break; case 't': /* create station table */ ctbl = G_TRUE; break; case 'l': /* list fields */ lfld = G_TRUE; break; case 'd': /* dump the shape file */ dump = G_TRUE; break; case 'h': /* display help */ default: ip_help ( prognm, &pagflg, &ier, strlen(prognm) ); exit ( 0 ); break; } } if ( optind == argc || argc - optind > MAXSHP ) { ip_help ( prognm, &pagflg, &ier, strlen(prognm) ); exit ( -1 ); } /*======================== Read the shape file ========================*/ /* * Loop over input files. */ currec = NULL; numrec = 0; numfil = argc - optind; for ( nf = 0; nf < numfil; nf++ ) { /* * Get the input names and open them. */ if ( debug_flag ) { printf ( "File %d: %s\n", nf, argv[optind+nf] ); } strcpy ( dbfnam[nf], argv[optind+nf] ); strcat ( dbfnam[nf], ".dbf" ); strcpy ( shxnam[nf], argv[optind+nf] ); strcat ( shxnam[nf], ".shx" ); strcpy ( shpnam[nf], argv[optind+nf] ); strcat ( shpnam[nf], ".shp" ); cfl_inqr ( dbfnam[nf], NULL, &flen, dbfnam[nf], &ier ); dbffp = cfl_ropn ( dbfnam[nf], NULL, &ier ); if ( ier != 0 ) { fprintf ( stderr, "File %s does not exist.\n", dbfnam[nf] ); exit ( -1 ); } cfl_inqr ( shxnam[nf], NULL, &flen, shxnam[nf], &ier ); shxfp = cfl_ropn ( shxnam[nf], NULL, &ier ); if ( ier != 0 ) { fprintf ( stderr, "File %s does not exist.\n", shxnam[nf] ); exit ( -1 ); } cfl_inqr ( shpnam[nf], NULL, &flen, shpnam[nf], &ier ); shpfp = cfl_ropn ( shpnam[nf], NULL, &ier ); if ( ier != 0 ) { fprintf ( stderr, "File %s does not exist.\n", shpnam[nf] ); exit ( -1 ); } /* * Detect platform endian. */ cfl_read ( shpfp, INTEGER_SIZE, (unsigned char *)&file_code, &nbin, &ier ); if ( file_code == 9994 ) { mch_endian = BIG; } else { mch_endian = LITTLE; } /* * Read database header. */ shp_rdbh ( dbffp, &dbfhdr, &ier ); numrec += dbfhdr.nrec; if ( lfld == G_TRUE ) { for ( ifld = 0; ifld < dbfhdr.nfld; ifld++ ) { printf ( "Field: %s\n", dbfhdr.dbflds[ifld].name ); } } else { /* * Read shape record and construct an internal list. */ for ( rec = 0; rec < dbfhdr.nrec; rec++ ) { /* * Read record field data. */ shp_rdbf ( dbffp, rec, &dbfhdr, &ier ); /* * Read record index. */ shp_rshx ( shxfp, rec, &shxrec, &ier ); /* * Read record data. */ shp_rshp ( shpfp, &dbfhdr, &shxrec, &newrec, &ier ); /* * Add the new record on record list. */ newrec->prvrec = currec; if ( currec != NULL ) { currec->nxtrec = newrec; } else { reclst = newrec; } currec = newrec; } } /* * Close up opened files. */ cfl_clos ( dbffp, &ier ); cfl_clos ( shxfp, &ier ); cfl_clos ( shpfp, &ier ); } if ( lfld == G_TRUE ) { shp_mfreeall ( ); exit ( 0 ); } /*======================== Read the shape exception table =============*/ _shpException = NULL; _numShpException = 0; shp_rdException ( &ier ); /*======================= Starting Post-Process =======================*/ /* * Dump shapefile records. */ if ( dump == G_TRUE ) { for ( rec = 0, currec = reclst; rec < numrec; rec++, currec = currec->nxtrec ) { shp_wfld ( stdout, currec, &ier ); shp_wrec ( stdout, currec, &ier ); } shp_mfreeall ( ); exit ( 0 ); } /* * Split record part if it has more than MAXOUT number of points * or it crosses the international dateline. */ shp_splt ( reclst, numrec, &ier ); /* * Detect the map type. */ shp_mtyp ( dbfnam, numfil, &ier ); if ( maptyp == 0 ) { fprintf ( stderr, "Unknown Map Type.\n" ); exit ( -1 ); } /* * Delete not used records. */ shp_drec ( &reclst, &numrec, &ier ); /* * Combine records that have the same key. */ shp_cmbn ( reclst, &numrec, &ier ); /* * Compute record centroid. */ mode = 1; iunit = itype = 1; xsize = ysize = 1.0F; strcpy ( device, "GN" ); strcpy ( filnam, "SHPCV" ); /* * Use North STR projection. */ strcpy ( proj, "STR" ); angle1 = 90.0F; angle2 = -90.0F; angle3 = 0.0F; lllat = -15.0F; lllon = -135.0F; urlat = -15.0F; urlon = -135.0F; ginitp ( &mode, &istat, &ier ); gsdeva ( device, &iunit, filnam, &itype, &xsize, &ysize, &ier, strlen(device), strlen(filnam) ); gsmprj ( proj, &angle1, &angle2, &angle3, &lllat, &lllon, &urlat, &urlon, &ier, strlen(proj) ); for ( currec = reclst, rec = 0; rec < numrec; rec++, currec = currec->nxtrec ) { /* * Get the shape fips code, check if there is a match in * Shape Exception Table. If yes, get manually set * clon&clat value from the table directly. */ if ( sscanf(currec->fields[3].data, "%lu", &shp_fips) == 1 ) { exception_found = FALSE; for ( ii = 0; ii < _numShpException; ii++ ) { if ( _shpException[ii].fips == shp_fips ) { currec->cenlat = _shpException[ii].clat; currec->cenlon = _shpException[ii].clon; exception_found = TRUE; break; } } if ( exception_found ) continue; } /* * Get the shape id, check if there is a match in * Shape Exception Table. If yes, get manually set * clon&clat value from the table directly. */ exception_found = FALSE; for ( ii = 0; ii < _numShpException; ii++ ) { if ( strcasecmp(currec->fields[0].data, _shpException[ii].id) == 0 ) { currec->cenlat = _shpException[ii].clat; currec->cenlon = _shpException[ii].clon; exception_found = TRUE; break; } } if ( exception_found ) continue; /* * Calculate clon&clat mathematically from an algorithm. */ shp_gctr ( currec, &clon, &clat, &ier ); if ( ier == 0 ) { currec->cenlat = clat; currec->cenlon = clon; } else { currec->cenlat = RMISSD; currec->cenlon = RMISSD; } } /* the end of for ( currec ... */ /* * Reduce number of points. */ if ( rdpt == G_TRUE ) { for ( rec = 0, currec = reclst; rec < numrec; rec++, currec = currec->nxtrec ) { for ( prt = 0, curprt = currec->shpart; prt < currec->numprt; prt++, curprt = curprt->nxtprt ) { shp_thin ( curprt, ratio, &ier ); } } } /* * Create station table. */ if ( ctbl == G_TRUE ) { shp_ctbl ( reclst, numrec, &ier ); } /* * Create bound and bound info. */ if ( cbnd == G_TRUE ) { shp_cbnd ( reclst, numrec, &ier ); } /* * Clean up. */ shp_mfreeall ( ); return 0; }
static void tbl_npsa ( shp_record *shprec, int numrec, int *iret ) /************************************************************************ * tbl_npsa * * * * This function creates the Predictive Service Areas table files. * * * * tbl_npsa ( shprec, numrec, iret ) * * * * Input parameters: * * *shprec shp_record Shape record list * * numrec int Total number of records * * * * Output parameters: * * *iret int Return code * * 0 = Normal * ** * * Log: * * S. Jacobs/NCEP 4/10 Initial coding * * X. Guo/CWS 4/12 Increase variables(code,shrnam) * * size * ***********************************************************************/ { shp_record *currec; /* * The array size is from the specification. */ char code[20], name[81], shrnam[52]; int rec, ifld, len, ier; float clat, clon; int iclat, iclon; char *tblnam = NPSATBL; FILE *tblfp; /*---------------------------------------------------------------------*/ *iret = 0; tblfp = cfl_wopn ( tblnam, &ier ); if ( ier != 0 ) { fprintf ( stderr, "File %s open failed.\n", tblnam ); exit ( -1 ); } for ( currec = shprec, rec = 0; rec < numrec; rec++, currec = currec->nxtrec ) { for ( ifld = 0; ifld < currec->numfld; ifld++ ) { if ( strncmp ( currec->fields[ifld].name, "NAT_CODE", strlen("NAT_CODE") ) == 0 ) { strcpy ( code, currec->fields[ifld].data ); cst_lstr ( code, &len, &ier ); code[len] = '\0'; } else if ( strncmp ( currec->fields[ifld].name, "PSA_NAME", strlen("PSA_NAME") ) == 0 ) { strcpy ( name, currec->fields[ifld].data ); cst_lstr ( name, &len, &ier ); name[len] = '\0'; cst_rspc ( name, &ier ); abbreviate ( name, 50, shrnam, &ier ); } } if ( strlen(shrnam) == 0 ) { strcpy ( shrnam, code ); } shp_gctr ( currec, &clon, &clat, &ier ); iclat = (int)(ROUNDUP(clat)*100.); iclon = (int)(ROUNDUP(clon)*100.); fprintf ( tblfp, "%-8.8s %6.6d %-32.32s -- US %5d %6d %5d %2d\n", code, 999999, shrnam, iclat, iclon, 0, 0 ); } cfl_clos ( tblfp, &ier ); }