00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cmath>
00024 #include <string>
00025
00026 #include "builder.h"
00027
00028 #include "qgslogger.h"
00029
00030 Builder::Builder( std::string theFname,
00031 int theShapefileType,
00032 double *theGrpXVals, double *theGrpYVals,
00033 std::string *theGrpNames,
00034 int theInsertCount,
00035 bool theConvertText ) :
00036 fname( theFname ),
00037 shapefileType( theShapefileType ),
00038 grpXVals( theGrpXVals ),
00039 grpYVals( theGrpYVals ),
00040 grpNames( theGrpNames ),
00041 insertCount( theInsertCount ),
00042 convertText( theConvertText ),
00043 fetchedprims( 0 ),
00044 fetchedtexts( 0 ),
00045 ignoringBlock( false ),
00046 awaiting_polyline_vertices( 0 ),
00047 current_polyline_pointcount( 0 ),
00048 currentBlockX( 0.0 ),
00049 currentBlockY( 0.0 )
00050 {
00051 }
00052
00053 Builder::~Builder()
00054 {
00055 polyVertex.clear();
00056 shpObjects.clear();
00057 textObjects.clear();
00058 }
00059
00060 int Builder::textObjectsSize()
00061 {
00062 return textObjects.size();
00063 }
00064
00065 std::string Builder::outputShp()
00066 {
00067 return outputshp;
00068 }
00069
00070 std::string Builder::outputTShp()
00071 {
00072 return outputtshp;
00073 }
00074
00075 void Builder::addBlock( const DL_BlockData& data )
00076 {
00077 QgsDebugMsg( "start block." );
00078
00079 if ( data.name.compare( "ADCADD_ZZ" ) == 0 )
00080 {
00081 QgsDebugMsg( QString( "Ignoring block %1" ).arg( data.name.c_str() ) );
00082 ignoringBlock = true;
00083 }
00084 else
00085 {
00086 for ( int i = 0; i < insertCount; i++ )
00087 {
00088 if ( grpNames[i] == data.name )
00089 {
00090 currentBlockX = grpXVals[i];
00091 currentBlockY = grpYVals[i];
00092 QgsDebugMsg( QString( "Found coord for block: (%1,%2)" ).arg( grpXVals[i] ).arg( grpYVals[i] ) );
00093 }
00094 }
00095 }
00096 }
00097
00098 void Builder::endBlock()
00099 {
00100 FinalizeAnyPolyline();
00101
00102 currentBlockX = 0.0;
00103 currentBlockY = 0.0;
00104 ignoringBlock = false;
00105
00106 QgsDebugMsg( "end block." );
00107 }
00108
00109 void Builder::addLayer( const DL_LayerData& data )
00110 {
00111 QgsDebugMsg( QString( "Layer: %1" ).arg( data.name.c_str() ) );
00112 }
00113
00114 void Builder::addPoint( const DL_PointData& data )
00115 {
00116 if ( shapefileType != SHPT_POINT )
00117 {
00118 QgsDebugMsg( "ignoring point" );
00119 return;
00120 }
00121
00122 QgsDebugMsg( QString( "point (%1,%2,%3)" ).arg( data.x ).arg( data.y ).arg( data.z ) );
00123
00124 if ( ignoringBlock )
00125 {
00126 QgsDebugMsg( "skipping point in block." );
00127 return;
00128 }
00129
00130
00131 double x = data.x + currentBlockX;
00132 double y = data.y + currentBlockY;
00133 double z = data.z;
00134
00135 SHPObject *psObject;
00136 psObject = SHPCreateObject( shapefileType, fetchedprims, 0, NULL, NULL, 1, &x, &y, &z, NULL );
00137
00138 shpObjects.push_back( psObject );
00139
00140 fetchedprims++;
00141 }
00142
00143 void Builder::addLine( const DL_LineData& data )
00144 {
00145
00146
00147
00148 if ( shapefileType != SHPT_ARC )
00149 {
00150 QgsDebugMsg( "ignoring line" );
00151 return;
00152 }
00153
00154 QgsDebugMsg( QString( "line %1,%2,%3 %4,%5,%6" )
00155 .arg( data.x1 ).arg( data.y1 ).arg( data.z1 )
00156 .arg( data.x2 ).arg( data.y2 ).arg( data.z2 ) );
00157
00158 if ( ignoringBlock )
00159 {
00160 QgsDebugMsg( "skipping line in block." );
00161 return;
00162 }
00163
00164
00165 double xv[2], yv[2], zv[2];
00166 xv[0] = data.x1 + currentBlockX;
00167 yv[0] = data.y1 + currentBlockY;
00168 zv[0] = data.z1;
00169
00170 xv[1] = data.x2 + currentBlockX;
00171 yv[1] = data.y2 + currentBlockY;
00172 zv[1] = data.z2;
00173
00174 SHPObject *psObject;
00175
00176 psObject = SHPCreateObject( shapefileType, fetchedprims, 0, NULL, NULL, 2, xv, yv, zv, NULL );
00177
00178 shpObjects.push_back( psObject );
00179
00180 fetchedprims++;
00181 }
00182
00183
00184 void Builder::addPolyline( const DL_PolylineData& data )
00185 {
00186 if ( shapefileType != SHPT_ARC && shapefileType != SHPT_POLYGON )
00187 {
00188 QgsDebugMsg( "ignoring polyline" );
00189 return;
00190 }
00191
00192 QgsDebugMsg( "reading polyline - expecting vertices" );
00193
00194 if ( ignoringBlock )
00195 {
00196 QgsDebugMsg( "skipping polyline in block" );
00197 return;
00198 }
00199
00200
00201 if ( current_polyline_pointcount > 0 )
00202 {
00203 if ( current_polyline_willclose )
00204 {
00205
00206 DL_VertexData myVertex;
00207
00208 myVertex.x = closePolyX;
00209 myVertex.y = closePolyY;
00210 myVertex.z = closePolyZ;
00211
00212 polyVertex.push_back( myVertex );
00213
00214 }
00215
00216 SHPObject *psShape;
00217 int dim = polyVertex.size();
00218 double *xv = new double[dim];
00219 double *yv = new double[dim];
00220 double *zv = new double[dim];
00221
00222 for ( int i = 0; i < dim; i++ )
00223 {
00224 xv[i] = polyVertex[i].x;
00225 yv[i] = polyVertex[i].y;
00226 zv[i] = polyVertex[i].z;
00227 }
00228
00229 psShape = SHPCreateObject( shapefileType, fetchedprims, 0, NULL, NULL, dim, xv, yv, zv, NULL );
00230
00231 delete [] xv;
00232 delete [] yv;
00233 delete [] zv;
00234
00235 shpObjects.push_back( psShape );
00236
00237
00238 fetchedprims++;
00239
00240 polyVertex.clear();
00241
00242 QgsDebugMsg( QString( "polyline prepared: %1" ).arg( fetchedprims - 1 ) );
00243 current_polyline_pointcount = 0;
00244 }
00245
00246
00247
00248
00249 if ( data.flags == 1 || data.flags == 32 )
00250 {
00251 current_polyline_willclose = true;
00252 store_next_vertex_for_polyline_close = true;
00253 }
00254 else
00255 {
00256 current_polyline_willclose = false;
00257 store_next_vertex_for_polyline_close = false;
00258 }
00259
00260 current_polyline_pointcount = 0;
00261
00262 }
00263
00264
00265 void Builder::addVertex( const DL_VertexData& data )
00266 {
00267 if ( shapefileType != SHPT_ARC && shapefileType != SHPT_POLYGON )
00268 {
00269 QgsDebugMsg( "ignoring vertex" );
00270 return;
00271 }
00272
00273 QgsDebugMsg( QString( "vertex (%1,%2,%3)" ).arg( data.x ).arg( data.y ).arg( data.z ) );
00274
00275 if ( ignoringBlock )
00276 {
00277 QgsDebugMsg( "skipping vertex in block" );
00278 return;
00279 }
00280
00281 DL_VertexData myVertex;
00282 myVertex.x = data.x + currentBlockX;
00283 myVertex.y = data.y + currentBlockY;
00284 myVertex.z = data.z;
00285
00286 polyVertex.push_back( myVertex );
00287
00288 current_polyline_pointcount++;
00289
00290 if ( store_next_vertex_for_polyline_close )
00291 {
00292 store_next_vertex_for_polyline_close = false;
00293 closePolyX = data.x + currentBlockX;
00294 closePolyY = data.y + currentBlockY;
00295 closePolyZ = data.z;
00296 }
00297 }
00298
00299
00300 void Builder::endSequence()
00301 {
00302 QgsDebugMsg( "endSequence" );
00303 }
00304
00305 void Builder::addArc( const DL_ArcData& data )
00306 {
00307 if ( shapefileType != SHPT_ARC )
00308 {
00309 QgsDebugMsg( "ignoring arc" );
00310 return;
00311 }
00312
00313 int fromAngle = ( int ) data.angle1 + 1;
00314 int toAngle = ( int ) data.angle2 + 1;
00315
00316 QgsDebugMsg( QString( "arc (%1,%2,%3 r=%4 a1=%5 a2=%6)" )
00317 .arg( data.cx ).arg( data.cy ).arg( data.cz )
00318 .arg( data.radius )
00319 .arg( data.angle1 ).arg( data.angle2 ) );
00320
00321 if ( ignoringBlock )
00322 {
00323 QgsDebugMsg( "skipping arc in block" );
00324 return;
00325 }
00326
00327 register int i = 0;
00328 register long shpIndex = 0;
00329
00330
00331
00332 double radianMeasure;
00333
00334 std::vector <DL_PointData> arcPoints;
00335 DL_PointData myPoint;
00336
00337 for ( i = fromAngle; ; i++, shpIndex++ )
00338 {
00339 if ( i > 360 )
00340 i = 0;
00341
00342 if ( shpIndex > 1000 )
00343 break;
00344
00345 radianMeasure = i * M_PI / 180.0;
00346
00347 myPoint.x = data.radius * cos( radianMeasure ) + data.cx + currentBlockX;
00348 myPoint.y = data.radius * sin( radianMeasure ) + data.cy + currentBlockY;
00349 myPoint.z = data.cz;
00350
00351 arcPoints.push_back( myPoint );
00352
00353 if ( i == toAngle )
00354 break;
00355 }
00356
00357
00358
00359 SHPObject *psShape;
00360 int dim = arcPoints.size();
00361 double *xv = new double[dim];
00362 double *yv = new double[dim];
00363 double *zv = new double[dim];
00364
00365 for ( int i = 0; i < dim; i++ )
00366 {
00367 xv[i] = arcPoints[i].x;
00368 yv[i] = arcPoints[i].y;
00369 zv[i] = arcPoints[i].z;
00370
00371 }
00372
00373 psShape = SHPCreateObject( shapefileType, fetchedprims, 0, NULL, NULL, dim, xv, yv, zv, NULL );
00374
00375 delete [] xv;
00376 delete [] yv;
00377 delete [] zv;
00378
00379 shpObjects.push_back( psShape );
00380
00381 fetchedprims++;
00382
00383 arcPoints.clear();
00384
00385 }
00386
00387
00388 void Builder::addCircle( const DL_CircleData& data )
00389 {
00390 if ( shapefileType != SHPT_ARC && shapefileType != SHPT_POLYGON )
00391 {
00392 QgsDebugMsg( "ignoring circle" );
00393 return;
00394 }
00395
00396 QgsDebugMsg( QString( "circle (%1,%2,%3 r=%4)" ).arg( data.cx ).arg( data.cy ).arg( data.cz ).arg( data.radius ) );
00397
00398 if ( ignoringBlock )
00399 {
00400 QgsDebugMsg( "skipping circle in block" );
00401 return;
00402 }
00403
00404
00405 std::vector <DL_PointData> circlePoints;
00406 DL_PointData myPoint;
00407
00408
00409 register long shpIndex = 0;
00410 for ( double i = 0.0; i <= 2*M_PI; i += M_PI / 180.0, shpIndex++ )
00411 {
00412 myPoint.x = data.radius * cos( i ) + data.cx + currentBlockX;
00413 myPoint.y = data.radius * sin( i ) + data.cy + currentBlockY;
00414 myPoint.z = data.cz;
00415
00416 circlePoints.push_back( myPoint );
00417 }
00418
00419 SHPObject *psShape;
00420 int dim = circlePoints.size();
00421 double *xv = new double[dim];
00422 double *yv = new double[dim];
00423 double *zv = new double[dim];
00424
00425 for ( int i = 0; i < dim; i++ )
00426 {
00427 xv[i] = circlePoints[i].x;
00428 yv[i] = circlePoints[i].y;
00429 zv[i] = circlePoints[i].z;
00430 }
00431
00432 psShape = SHPCreateObject( shapefileType, fetchedprims, 0, NULL, NULL, dim, xv, yv, zv, NULL );
00433
00434 delete [] xv;
00435 delete [] yv;
00436 delete [] zv;
00437
00438 shpObjects.push_back( psShape );
00439
00440 fetchedprims++;
00441
00442 circlePoints.clear();
00443 }
00444
00445 void Builder::addText( const DL_TextData &data )
00446 {
00447 if ( convertText )
00448 {
00449 DL_TextData myText(
00450 data.ipx + currentBlockX, data.ipy + currentBlockY, data.ipz,
00451 data.apx, data.apy, data.apz,
00452 data.height, data.xScaleFactor, data.textGenerationFlags,
00453 data.hJustification, data.vJustification,
00454 data.text, data.style, data.angle
00455 );
00456
00457 textObjects.push_back( myText );
00458
00459 QgsDebugMsg( QString( "text: %1" ).arg( data.text.c_str() ) );
00460 fetchedtexts++;
00461 }
00462 }
00463
00464 void Builder::FinalizeAnyPolyline()
00465 {
00466
00467 if ( current_polyline_pointcount > 0 )
00468 {
00469 if ( current_polyline_willclose )
00470 {
00471 DL_VertexData myVertex;
00472 myVertex.x = closePolyX;
00473 myVertex.y = closePolyY;
00474 myVertex.z = closePolyZ;
00475
00476 polyVertex.push_back( myVertex );
00477 }
00478
00479 SHPObject *psObject;
00480 int dim = polyVertex.size();
00481 double *xv = new double[dim];
00482 double *yv = new double[dim];
00483 double *zv = new double[dim];
00484
00485 for ( int i = 0; i < dim; i++ )
00486 {
00487 xv[i] = polyVertex[i].x;
00488 yv[i] = polyVertex[i].y;
00489 zv[i] = polyVertex[i].z;
00490 }
00491
00492 psObject = SHPCreateObject( shapefileType, fetchedprims, 0, NULL, NULL, dim, xv, yv, zv, NULL );
00493
00494 delete [] xv;
00495 delete [] yv;
00496 delete [] zv;
00497
00498 shpObjects.push_back( psObject );
00499
00500 polyVertex.clear();
00501
00502 fetchedprims++;
00503
00504 QgsDebugMsg( QString( "Finalized adding of polyline shape %1" ).arg( fetchedprims - 1 ) );
00505 current_polyline_pointcount = 0;
00506 }
00507 }
00508
00509 void Builder::print_shpObjects()
00510 {
00511 int dim = shpObjects.size();
00512 int dimTexts = textObjects.size();
00513
00514 QgsDebugMsg( QString( "Number of primitives: %1" ).arg( dim ) );
00515 QgsDebugMsg( QString( "Number of text fields: %1" ).arg( dimTexts ) );
00516
00517 SHPHandle hSHP;
00518
00519 if ( fname.substr( fname.length() - 4 ).compare( ".shp" ) == 0 )
00520 {
00521 outputdbf = fname;
00522 outputdbf = outputdbf.replace(( outputdbf.length() - 3 ), outputdbf.length(), "dbf" );
00523 outputshp = fname;
00524 outputshp = outputshp.replace(( outputshp.length() - 3 ), outputshp.length(), "shp" );
00525 outputtdbf = fname;
00526 outputtdbf = outputtdbf.replace(( outputtdbf.length() - 4 ), outputtdbf.length(), "_texts.dbf" );
00527 outputtshp = fname;
00528 outputtshp = outputtshp.replace(( outputtshp.length() - 4 ), outputtshp.length(), "_texts.shp" );
00529 }
00530 else
00531 {
00532 outputdbf = fname;
00533 outputdbf = outputdbf.append( ".dbf" );
00534 outputshp = fname;
00535 outputshp = outputdbf.append( ".shp" );
00536 outputtdbf = fname;
00537 outputtdbf = outputtdbf.append( ".dbf" );
00538 outputtshp = fname;
00539 outputtshp = outputtdbf.append( ".shp" );
00540 }
00541
00542 DBFHandle dbffile = DBFCreate( outputdbf.c_str() );
00543 DBFAddField( dbffile, "myid", FTInteger, 10, 0 );
00544
00545 hSHP = SHPCreate( outputshp.c_str(), shapefileType );
00546
00547 QgsDebugMsg( "Writing to main shp file..." );
00548
00549 for ( int i = 0; i < dim; i++ )
00550 {
00551 SHPWriteObject( hSHP, -1, shpObjects[i] );
00552 SHPDestroyObject( shpObjects[i] );
00553 DBFWriteIntegerAttribute( dbffile, i, 0, i );
00554 }
00555
00556 SHPClose( hSHP );
00557 DBFClose( dbffile );
00558
00559 QgsDebugMsg( "Done!" );
00560
00561 if ( convertText && dimTexts > 0 )
00562 {
00563 SHPHandle thSHP;
00564
00565 DBFHandle Tdbffile = DBFCreate( outputtdbf.c_str() );
00566 thSHP = SHPCreate( outputtshp.c_str(), SHPT_POINT );
00567
00568 DBFAddField( Tdbffile, "tipx", FTDouble, 20, 10 );
00569 DBFAddField( Tdbffile, "tipy", FTDouble, 20, 10 );
00570 DBFAddField( Tdbffile, "tipz", FTDouble, 20, 10 );
00571 DBFAddField( Tdbffile, "tapx", FTDouble, 20, 10 );
00572 DBFAddField( Tdbffile, "tapy", FTDouble, 20, 10 );
00573 DBFAddField( Tdbffile, "tapz", FTDouble, 20, 10 );
00574 DBFAddField( Tdbffile, "height", FTDouble, 20, 10 );
00575 DBFAddField( Tdbffile, "scale", FTDouble, 20, 10 );
00576 DBFAddField( Tdbffile, "flags", FTInteger, 10, 0 );
00577 DBFAddField( Tdbffile, "hjust", FTInteger, 10, 0 );
00578 DBFAddField( Tdbffile, "vjust", FTInteger, 10, 0 );
00579 DBFAddField( Tdbffile, "text", FTString, 50, 0 );
00580 DBFAddField( Tdbffile, "style", FTString, 50, 0 );
00581 DBFAddField( Tdbffile, "angle", FTDouble, 20, 10 );
00582
00583 QgsDebugMsg( "Writing Texts' shp File..." );
00584
00585 for ( int i = 0; i < dimTexts; i++ )
00586 {
00587 SHPObject *psObject;
00588 double x = textObjects[i].ipx;
00589 double y = textObjects[i].ipy;
00590 double z = textObjects[i].ipz;
00591 psObject = SHPCreateObject( SHPT_POINT, i, 0, NULL, NULL, 1, &x, &y, &z, NULL );
00592
00593 SHPWriteObject( thSHP, -1, psObject );
00594
00595 DBFWriteDoubleAttribute( Tdbffile, i, 0, textObjects[i].ipx );
00596 DBFWriteDoubleAttribute( Tdbffile, i, 1, textObjects[i].ipy );
00597 DBFWriteDoubleAttribute( Tdbffile, i, 2, textObjects[i].ipz );
00598
00599 DBFWriteDoubleAttribute( Tdbffile, i, 3, textObjects[i].apx );
00600 DBFWriteDoubleAttribute( Tdbffile, i, 4, textObjects[i].apy );
00601 DBFWriteDoubleAttribute( Tdbffile, i, 5, textObjects[i].apz );
00602
00603 DBFWriteDoubleAttribute( Tdbffile, i, 6, textObjects[i].height );
00604 DBFWriteDoubleAttribute( Tdbffile, i, 7, textObjects[i].xScaleFactor );
00605 DBFWriteIntegerAttribute( Tdbffile, i, 8, textObjects[i].textGenerationFlags );
00606
00607 DBFWriteIntegerAttribute( Tdbffile, i, 9, textObjects[i].hJustification );
00608 DBFWriteIntegerAttribute( Tdbffile, i, 10, textObjects[i].vJustification );
00609
00610 DBFWriteStringAttribute( Tdbffile, i, 11, textObjects[i].text.c_str() );
00611 DBFWriteStringAttribute( Tdbffile, i, 12, textObjects[i].style.c_str() );
00612
00613 DBFWriteDoubleAttribute( Tdbffile, i, 13, textObjects[i].angle );
00614
00615 SHPDestroyObject( psObject );
00616 }
00617 SHPClose( thSHP );
00618 DBFClose( Tdbffile );
00619
00620 QgsDebugMsg( "Done!" );
00621 }
00622 }