00001 #include "glimslinedata.h" 00002 #include "TraceLog.h" 00003 00004 00005 GLIMSLineData::GLIMSLineData( ) : 00006 mDefGID( -1 ), 00007 mDefLDF( -1 ) { 00008 00009 } 00010 00011 bool GLIMSLineData::toXML( QDomDocument &doc, 00012 QDomElement &elem, 00013 std::string id ) { 00014 QDomElement base = doc.createElement( "LineData" ); 00015 if ( id != "" ) 00016 base.setAttribute( "id", id.c_str() ); 00017 elem.appendChild( base ); 00018 00019 mLDFSet.toXML( doc, base ); 00020 for ( unsigned int iline=0; iline < mLLSet.size(); iline++ ) { 00021 GlacierLine &gline = 00022 dynamic_cast<GlacierLine&>( *mLLSet[iline] ); 00023 gline.toXML( doc, base ); 00024 } 00025 return true; 00026 } 00027 00028 bool GLIMSLineData::fromXML( QDomElement &elem ) { 00029 if ( std::string( "LineData" ).compare( (const char*)elem.tagName() ) ) 00030 return false; 00031 00032 QDomNode node = elem.firstChild(); 00033 if ( !node.isElement() ) 00034 return false; 00035 QDomElement e = node.toElement(); 00036 if ( !mLDFSet.fromXML( e ) ) 00037 return false; 00038 00039 node = e.nextSibling(); 00040 while ( !node.isNull() ) { 00041 if ( !node.isElement() ) 00042 return false; 00043 e = node.toElement(); 00044 GlacierLine *llline, *xyline; 00045 llline = new GlacierLine; 00046 xyline = new GlacierLine; 00047 if ( !llline->fromXML( e ) ) 00048 return false; 00049 00050 if ( llline->mLDF != -1 ) { 00051 DspAttr &attr = llline->mAttr; 00052 attr.color = GLIMSGlobals::AVAILCOLORS[ mLDFSet[llline->mLDF].mColor ]; 00053 attr.style = (Qt::PenStyle)mLDFSet[llline->mLDF].mStyle; 00054 attr.width = mLDFSet[llline->mLDF].mWidth; 00055 } 00056 00057 *xyline = *llline; 00058 mLLSet.push_back( llline ); 00059 mXYSet.push_back( xyline ); 00060 node = node.nextSibling(); 00061 } 00062 00063 transformDataset(); 00064 emit datasetChanged(); 00065 return true; 00066 } 00067 00068 void GLIMSLineData::addLine( Node &xynode ) { 00069 // basic shape attributes 00070 DspAttr attr; 00071 00072 // 00073 GlacierLine *llline = new GlacierLine( mDefGID, mDefLDF ); 00074 GlacierLine *xyline = new GlacierLine( mDefGID, mDefLDF ); 00075 00076 Node llnode = xynode; 00077 00078 mImg->getLL( llnode.x, llnode.y ); 00079 llline->nodeset().push_back( llnode ); 00080 xyline->nodeset().push_back( xynode ); 00081 00082 if ( mDefLDF != -1 ) { 00083 LineDef &ldf = mLDFSet[mDefLDF]; 00084 attr.color = GLIMSGlobals::AVAILCOLORS[ldf.mColor]; 00085 attr.style = (Qt::PenStyle)ldf.mStyle; 00086 attr.width = ldf.mWidth; 00087 } 00088 xyline->setAttr( attr ); 00089 mXYSet.push_back( xyline ); 00090 mLLSet.push_back( llline ); 00091 00092 // push history information onto history stack 00093 mUndoSel.push( mSelSet ); 00094 mHistory.push(*xyline, mXYSet.size() - 1, -1, addedLine) ; 00095 mRedoHistory.clear() ; 00096 00097 emit datasetChanged(); 00098 } 00099 00100 00101 void GLIMSLineData::restoreLine( GlacierLine &line, int iline ) { 00102 GlacierLine * newXYLine = new GlacierLine ; 00103 GlacierLine * newLLLine = new GlacierLine ; 00104 *newXYLine = line ; 00105 *newLLLine = line ; 00106 00107 int numNodes = (int)(newLLLine->size()) ; 00108 for (int nodeNdx = 0 ; nodeNdx < numNodes ; nodeNdx++) { 00109 mImg->getLL((*newLLLine)[nodeNdx].x, (*newLLLine)[nodeNdx].y) ; 00110 } 00111 00112 if ( iline < 0 || iline >= (int)mXYSet.size() ) { 00113 mXYSet.push_back( newXYLine ); 00114 mLLSet.push_back( newLLLine ); 00115 iline = (int)mXYSet.size() - 1 ; 00116 } 00117 else { 00119 mXYSet.insert( mXYSet.begin() + iline, newXYLine ); 00120 mLLSet.insert( mLLSet.begin() + iline, newLLLine ); 00121 // mXYSet.push_back( newXYLine ); 00122 // mLLSet.push_back( newLLLine ); 00123 // iline = (int)mXYSet.size() - 1 ; 00124 } 00125 emit datasetChanged(); 00126 } 00127 00128 00129 00130 void GLIMSLineData::delLine( int iline ) { 00131 if ( iline < 0 || iline >= (int)mXYSet.size() ) return; 00132 00133 GlacierLine * deleteLine = new GlacierLine ; 00134 (*deleteLine) = (*(GlacierLine*)(mXYSet[iline])) ; 00135 00136 mUndoSel.push( mSelSet ); 00137 mHistory.push(*deleteLine, iline, -1, deletedLine) ; 00138 mRedoHistory.clear() ; 00139 00140 mXYSet.erase( mXYSet.begin() + iline ); 00141 mLLSet.erase( mLLSet.begin() + iline ); 00142 } 00143 00144 void GLIMSLineData::removeLine( int iline ) { 00145 00146 if ( iline < 0 || iline >= (int)mXYSet.size() ) return; 00147 mXYSet.erase( mXYSet.begin() + iline ); 00148 mLLSet.erase( mLLSet.begin() + iline ); 00149 } 00150 00151 00152 void GLIMSLineData::breakLine( int iline, int inode ) { 00153 int i; 00154 int nnodes; 00155 GlacierLine *l1, *l2; 00156 00157 // get the line to be broken 00158 Shape &xys = *mXYSet[iline]; 00159 Shape &lls = *mLLSet[iline]; 00160 GlacierLine &xyline = dynamic_cast<GlacierLine&>( xys ); 00161 GlacierLine &llline = dynamic_cast<GlacierLine&>( lls ); 00162 00163 nnodes = (int)xyline.size(); 00164 if ( inode <= 0 || inode >= nnodes-1 ) 00165 return; 00166 00167 00168 // push information about the old line onto the history stack 00169 mUndoSel.push( mSelSet ); 00170 mHistory.push(xyline, iline, inode, brokeLine) ; 00171 mRedoHistory.clear() ; 00172 00173 // create a new line (l1=XY and l2=lat-lon) with basic attribs of the 00174 // one being broken 00175 l1 = new GlacierLine( xyline.mGID, xyline.mLDF ); 00176 l2 = new GlacierLine( xyline.mGID, xyline.mLDF ); 00177 00178 // fill the line with copies of the nodes starting where the 00179 // line is being broken and going to the end 00180 for ( i=inode; i < nnodes; i++ ) { 00181 l1->nodeset().push_back( xyline[i] ); 00182 l2->nodeset().push_back( llline[i] ); 00183 } 00184 00185 // delete the nodes from the original line 00186 // that were copied into the new line above 00187 for ( i=nnodes-1; i > inode; i-- ) { 00188 xyline.delNode( i ); 00189 llline.delNode( i ); 00190 } 00191 00192 // store the new line 00193 mXYSet.push_back(l1) ; 00194 mLLSet.push_back(l2) ; 00195 00196 // push information about the new line onto the history stack 00197 mHistory.push(*l1, mXYSet.size() - 1, 0, brokeLine) ; 00198 mRedoHistory.clear() ; 00199 00200 emit datasetChanged(); 00201 return; 00202 } 00203 00204 // put a joined line back to the original two separate lines 00205 void GLIMSLineData::restoreJoinedLines(GlacierLine &line1, int iline1, 00206 GlacierLine &line2, int iline2, 00207 GlacierLineHistoryElement * h1, 00208 GlacierLineHistoryElement * h2) { 00209 00210 unsigned int i; // handy counter 00211 //int nnodes; // number of nodes 00212 00213 // get the line from data set that was the product of the join 00214 Shape &xys = *mXYSet[iline1]; 00215 Shape &lls = *mLLSet[iline1]; 00216 GlacierLine &xyline = dynamic_cast<GlacierLine&>( xys ); 00217 GlacierLine &llline = dynamic_cast<GlacierLine&>( lls ); 00218 00219 00220 // update history 00221 GlacierLine * storeLine = new GlacierLine ; 00222 (*storeLine) = xyline ; 00223 h1->setShape(storeLine) ; 00224 00225 // clear the line contents 00226 xyline.nodeset().clear() ; 00227 llline.nodeset().clear() ; 00228 00229 // revert the line to its original state (stored in 00230 // history before the join and passed in as param line1) 00231 xyline = line1 ; 00232 llline = xyline ; 00233 for (i = 0 ; i < llline.size() ; i++) { 00234 mImg->getLL(llline[i].x, llline[i].y) ; 00235 } 00236 00237 00238 // allocate a new line to recreate the second line 00239 // of the join into 00240 GlacierLine * l2xy = new GlacierLine ; 00241 GlacierLine * l2ll = new GlacierLine ; 00242 00243 // copy the original state of the second line (stored in 00244 // history before the join and passed in as param line2) 00245 // into the new line 00246 (*l2xy) = line2 ; 00247 (*l2ll) = (*l2xy) ; 00248 00249 // update history 00250 h2->setShape(l2xy) ; 00251 00252 // set the lat/lon information for the line 00253 for (i = 0 ; i < (*l2ll).size() ; i++) { 00254 mImg->getLL(((*l2ll)[i]).x, ((*l2ll)[i]).y) ; 00255 } 00256 00257 // store the new line in the line dataset 00258 mXYSet.insert((mXYSet.begin() + iline2), l2xy) ; 00259 mLLSet.insert((mLLSet.begin() + iline2), l2ll) ; 00260 00261 emit datasetChanged(); 00262 return; 00263 } 00264 00265 void GLIMSLineData::joinLine( int il1, 00266 int il2, 00267 int in1, 00268 int in2 ) { 00269 00270 // get the two lines to be joined 00271 Shape &xys1 = *mXYSet[il1]; 00272 Shape &xys2 = *mXYSet[il2]; 00273 Shape &lls1 = *mLLSet[il1]; 00274 Shape &lls2 = *mLLSet[il2]; 00275 00276 GlacierLine &xyl1 = dynamic_cast<GlacierLine&>( xys1 ); 00277 GlacierLine &xyl2 = dynamic_cast<GlacierLine&>( xys2 ); 00278 GlacierLine &lll1 = dynamic_cast<GlacierLine&>( lls1 ); 00279 GlacierLine &lll2 = dynamic_cast<GlacierLine&>( lls2 ); 00280 00281 // push history onto stack 00282 mUndoSel.push( mSelSet ); 00283 mHistory.push(xyl1, il1, in1, joinedLines) ; 00284 mHistory.push(xyl2, il2, in2, joinedLines) ; 00285 mRedoHistory.clear() ; 00286 00287 00288 // check to see if the nodes are at the ends of the lines 00289 if ( !(in1 == 0 || in1 == (int)xyl1.size()-1) || 00290 !(in2 == 0 || in2 == (int)xyl2.size()-1) ) 00291 return; 00292 00293 // if the node in line 1 to be joined is at the beginning of the line, 00294 // reverse the node order so it's at the end 00295 if ( in1 == 0 ) { 00296 std::reverse( xyl1.nodeset().begin(), xyl1.nodeset().end() ); 00297 std::reverse( lll1.nodeset().begin(), lll1.nodeset().end() ); 00298 } 00299 00300 // if the node in line 2 to be joined is at the end of the line, 00301 // reverse the node order so it's at the beginning 00302 if ( in2 != 0 ) { 00303 std::reverse( xyl2.nodeset().begin(), xyl2.nodeset().end() ); 00304 std::reverse( lll2.nodeset().begin(), lll2.nodeset().end() ); 00305 } 00306 00307 // put the nodes in line 2 to line 1 00308 for ( int inode=0; inode < (int)xyl2.size(); inode++ ) { 00309 xyl1.nodeset().push_back( xyl2[inode] ); 00310 lll1.nodeset().push_back( lll2[inode] ); 00311 } 00312 removeLine (il2) ; 00313 00314 emit datasetChanged(); 00315 return; 00316 } 00317 00318 void GLIMSLineData::rejoinLine( GlacierLine & originalLine, 00319 int il1, 00320 int il2, 00321 GlacierLineHistoryElement * h1, 00322 GlacierLineHistoryElement * h2) { 00323 00324 // get line from dataset 00325 Shape &xys = *mXYSet[il1]; 00326 Shape &lls = *mLLSet[il1]; 00327 00328 GlacierLine &xyl = dynamic_cast<GlacierLine&>( xys ); 00329 GlacierLine &lll = dynamic_cast<GlacierLine&>( lls ); 00330 00331 // update history 00332 GlacierLine * storeLine = new GlacierLine ; 00333 (*storeLine) = xyl ; 00334 h1->setShape(storeLine) ; 00335 00336 // empty out the line 00337 xyl.nodeset().clear() ; 00338 lll.nodeset().clear() ; 00339 00340 // restore stored line to active dataset 00341 xyl = originalLine ; 00342 lll = xyl ; 00343 00344 // recalc the lat-lon info 00345 for (unsigned int i = 0 ; i < lll.size() ; i++) { 00346 mImg->getLL(lll[i].x, lll[i].y) ; 00347 } 00348 00349 // update history 00350 // get second line from dataset 00351 Shape &xys2 = *mXYSet[il2]; 00352 GlacierLine &xyl2 = dynamic_cast<GlacierLine&>( xys2 ); 00353 h2->setShape(&xyl2) ; 00354 00355 // remove extra line 00356 removeLine (il2) ; 00357 00358 emit datasetChanged(); 00359 return; 00360 } 00361 00362 void GLIMSLineData::addLineNode( Node &node, 00363 int iline, 00364 int inode ) { 00365 if ( iline == -1 ) 00366 return; 00367 00368 if ( inode == -1 ) 00369 insertLineNode( node, iline ); 00370 else 00371 insertLineNode( node, iline, inode+1 ); 00372 emit datasetChanged(); 00373 00374 } 00375 00376 void GLIMSLineData::restoreLineNode( Node &node, 00377 int iline, 00378 int inode ) { 00379 00380 if ( iline == -1 ) 00381 return; 00382 00383 if ( inode == -1 ) 00384 reinsertLineNode( node, iline ); 00385 else 00386 reinsertLineNode( node, iline, inode ); 00387 00388 emit datasetChanged(); 00389 } 00390 00391 void GLIMSLineData::delLineNode( int iline, int inode ) { 00392 00393 Shape &xys = *mXYSet[iline]; 00394 Shape &lls = *mLLSet[iline]; 00395 Line &xyline = dynamic_cast<Line&>( xys ); 00396 Line &llline = dynamic_cast<Line&>( lls ); 00397 if ( xyline.size() <= 1 ) { 00398 delLine( iline ); 00399 } 00400 else { 00401 Node saveNode = xyline[inode] ; 00402 // dls 00403 mUndoSel.push( mSelSet ); 00404 mHistory.push(saveNode, iline, inode, deletedNode) ; 00405 mRedoHistory.clear() ; 00406 00407 xyline.delNode( inode ); 00408 llline.delNode( inode ); 00409 } 00410 emit datasetChanged(); 00411 } 00412 00413 void GLIMSLineData::removeLineNode( int iline, int inode ) { 00414 00415 Shape &xys = *mXYSet[iline]; 00416 Shape &lls = *mLLSet[iline]; 00417 Line &xyline = dynamic_cast<Line&>( xys ); 00418 Line &llline = dynamic_cast<Line&>( lls ); 00419 if ( xyline.size() <= 1 ) { 00420 // use non-history version of delete line 00421 removeLine( iline ); 00422 } 00423 else { 00424 xyline.delNode( inode ); 00425 llline.delNode( inode ); 00426 } 00427 emit datasetChanged(); 00428 } 00429 00430 void GLIMSLineData::moveLineNode( int iline, 00431 int inode, 00432 Node &xynode ) { 00433 Node llnode = xynode; 00434 mImg->getLL( llnode.x, llnode.y ); 00435 Shape &xys = *mXYSet[iline]; 00436 Shape &lls = *mLLSet[iline]; 00437 Line &xyline = dynamic_cast<Line&>( xys ); 00438 Line &llline = dynamic_cast<Line&>( lls ); 00439 00440 startMoveLineNode (iline, inode, xyline[inode]) ; 00441 00442 xyline[inode] = xynode; 00443 llline[inode] = llnode; 00444 00445 emit datasetChanged(); 00446 } 00447 00448 00457 void GLIMSLineData::startMoveLineNode( int iline, 00458 int inode, 00459 Node &xynode ) { 00460 00461 // make sure the node hasn't already been moving 00462 // kluge - see todo lists for this class 00463 GlacierLineHistoryElement * lastaction = mHistory.peek() ; 00464 bool moving = false ; 00465 if ( lastaction != NULL && 00466 lastaction->getAction() == movedNode && 00467 lastaction->getLineIndex() == iline && 00468 lastaction->getNodeIndex() == inode ) { 00469 moving = true ; 00470 } 00471 00472 if (!moving) { 00473 // push history information onto history stack 00474 Shape &xys = *mXYSet[iline] ; 00475 Line &xyline = dynamic_cast<Line&>( xys ); 00476 Node saveNode = xyline[inode] ; 00477 00478 mUndoSel.push( mSelSet ); 00479 mHistory.push(saveNode, iline, inode, movedNode) ; 00480 mRedoHistory.clear() ; 00481 } 00482 00483 // KLUGE ignore this - it's just to shut the compiler up 00484 double kluge = xynode.x ; 00485 kluge = kluge + 1.0 ; 00486 } 00487 00488 void GLIMSLineData::restoreMovedLineNode( int iline, 00489 int inode, 00490 Node &xynode ) { 00491 Node llnode = xynode; 00492 mImg->getLL( llnode.x, llnode.y ); 00493 Shape &xys = *mXYSet[iline]; 00494 Shape &lls = *mLLSet[iline]; 00495 Line &xyline = dynamic_cast<Line&>( xys ); 00496 Line &llline = dynamic_cast<Line&>( lls ); 00497 00498 xyline[inode] = xynode; 00499 llline[inode] = llnode; 00500 emit datasetChanged(); 00501 } 00502 00503 void GLIMSLineData::insertLineNode( Node &node, 00504 int iline, 00505 int inode ) { 00506 00507 std::vector<Node>::iterator itll, itxy; 00508 if ( iline == -1 ) 00509 return; 00510 00511 00512 Shape &lls = *mLLSet[iline]; 00513 Shape &xys = *mXYSet[iline]; 00514 Line &llline = dynamic_cast<Line&>( lls ); 00515 Line &xyline = dynamic_cast<Line&>( xys ); 00516 00517 if ( inode == -1 ) { 00518 itxy = xyline.nodeset().end(); 00519 itll = llline.nodeset().end(); 00520 } 00521 else { 00522 itxy = (xyline.nodeset().begin()+inode); 00523 itll = (llline.nodeset().begin()+inode); 00524 } 00525 00526 Node llnode = node; 00527 00528 mImg->getLL( llnode.x, llnode.y ); 00529 00530 xyline.nodeset().insert( itxy, node ); 00531 llline.nodeset().insert( itll, llnode ); 00532 00533 // push history information onto history stack 00534 Node saveNode = node ; 00535 mUndoSel.push( mSelSet ); 00536 mHistory.push(saveNode, iline, inode, insertedNode) ; 00537 mRedoHistory.clear() ; 00538 00539 emit datasetChanged(); 00540 } 00541 00542 void GLIMSLineData::reinsertLineNode( Node &node, 00543 int iline, 00544 int inode ) { 00545 00546 std::vector<Node>::iterator itll, itxy; 00547 if ( iline == -1 ) 00548 return; 00549 00550 Shape &lls = *mLLSet[iline]; 00551 Shape &xys = *mXYSet[iline]; 00552 Line &llline = dynamic_cast<Line&>( lls ); 00553 Line &xyline = dynamic_cast<Line&>( xys ); 00554 00556 if ( inode == -1 ) { 00557 itxy = xyline.nodeset().end(); 00558 itll = llline.nodeset().end(); 00559 } 00560 else if (inode == 0) { 00561 itxy = (xyline.nodeset().begin()); 00562 itll = (llline.nodeset().begin()); 00563 } 00564 else { 00565 // 1 is added to inode to convert from array counting (0,1,2..n) 00566 // to iterator counting (1,2,3..n) 00567 itxy = (xyline.nodeset().begin() + inode); 00568 itll = (llline.nodeset().begin() + inode); 00569 } 00570 00571 Node llnode = node; 00572 mImg->getLL( llnode.x, llnode.y ); 00573 xyline.nodeset().insert( itxy, node ); 00574 llline.nodeset().insert( itll, llnode ); 00575 emit datasetChanged(); 00576 } 00577 00578 00579 00580 GlacierLine* GLIMSLineData::toXY( GlacierLine *gl ) { 00581 if ( gl == NULL ) 00582 return NULL; 00583 00584 GlacierLine &llline = *gl; 00585 GlacierLine *gline = new GlacierLine( llline.mGID, llline.mLDF ); 00586 DspAttr &attr = gline->getAttr(); 00587 for ( unsigned int inode=0; inode < llline.size(); inode++ ) { 00588 Node xynode = llline[inode]; 00589 mImg->getXY( xynode.x, xynode.y ); 00590 gline->nodeset().push_back( xynode ); 00591 } 00592 LineDef &ldf = mLDFSet[ llline.mLDF ]; 00593 attr.color = GLIMSGlobals::AVAILCOLORS[ ldf.mColor ]; 00594 attr.style = (Qt::PenStyle)ldf.mStyle; 00595 attr.width = ldf.mWidth; 00596 return gline; 00597 } 00598 00611 void GLIMSLineData::pop( ) { 00612 // pop from the history and push onto the redo stack 00613 pop (&mHistory, &mRedoHistory, &mUndoSel, &mRedoSel) ; 00614 } 00615 00616 void GLIMSLineData::redo( ) { 00617 // pop from the redo stack and push onto the history stack 00618 pop (&mRedoHistory, &mHistory, &mRedoSel, &mUndoSel) ; 00619 } 00620 00621 void GLIMSLineData::pop( GlacierLineHistory * historyUndo, GlacierLineHistory * historyRedo, 00622 std::stack<SelectionSet> * selSetUndo, std::stack<SelectionSet> * selSetRedo) { 00623 00624 if (historyUndo->size() == 0 ) { 00625 return ; 00626 } 00627 GlacierLineHistoryElement * lastAction = historyUndo->pop() ; 00628 00629 if (lastAction != NULL) { 00630 switch (lastAction->getAction()) { 00631 case (deletedNode): 00632 00633 if (lastAction->getShape() != NULL) { 00634 // get a copy of the node that was deleted 00635 Node addBackNode = *((Node*)lastAction->getShape()) ; 00636 // get information about where to restore the node to 00637 int lndx = lastAction->getLineIndex() ; // line index - line this node belonged to 00638 int nndx = lastAction->getNodeIndex() ; // node index - what position this node 00639 // was in before it was deleted 00640 00641 // restore the node to its original position in the line 00642 restoreLineNode (addBackNode, lndx, nndx) ; 00643 lastAction->setAction(addedNode) ; 00644 historyRedo->push(lastAction) ; 00645 } 00646 break ; 00647 00648 case (deletedLine): 00649 00650 if (lastAction->getShape() != NULL) { 00651 // get a copy of the line that was deleted 00652 GlacierLine addBackLine = *((GlacierLine*)lastAction->getShape()) ; 00653 // get information about where to restore the line to 00654 int lndx = lastAction->getLineIndex() ; // line index - the original position of 00655 // the line in the line set before deletion 00656 00657 // restore the line to its original position in the line set 00658 restoreLine (addBackLine, lndx) ; 00659 lastAction->setAction(addedLine) ; 00660 historyRedo->push(lastAction) ; 00661 } 00662 break ; 00663 00664 case (addedNode): 00665 case (insertedNode): 00666 00667 if (lastAction->getShape() != NULL) { 00668 // get information about where to remove the node from 00669 int lndx = lastAction->getLineIndex() ; // line index - the original position of 00670 // the line in the line set the node was added to 00671 int nndx = lastAction->getNodeIndex() ; // node index - what position this node 00672 // was in after it was added 00673 00674 // restore the line to its original position in the line set 00675 removeLineNode(lndx, nndx) ; 00676 lastAction->setAction(deletedNode) ; 00677 historyRedo->push(lastAction) ; 00678 } 00679 break ; 00680 00681 case (addedLine): 00682 00683 if (lastAction->getShape() != NULL) { 00684 // get information about where to remove the line from 00685 int lndx = lastAction->getLineIndex() ; // line index - the original position of 00686 // the line in the line set when it was added 00687 00688 // restore the line to its original position in the line set 00689 removeLine(lndx) ; 00690 lastAction->setAction(deletedLine) ; 00691 historyRedo->push(lastAction) ; 00692 } 00693 break ; 00694 00695 case (movedNode): 00696 if (lastAction->getShape() != NULL) { 00697 // get a copy of the node before it was moved 00698 Node originalNode = *((Node*)lastAction->getShape()) ; 00699 // get information about what node to move back to its original position 00700 int lndx = lastAction->getLineIndex() ; // line index - the index of the line 00701 // in the line set with the moved node 00702 int nndx = lastAction->getNodeIndex() ; // node index - the position of the moved 00703 // node in the line 00704 00705 00706 // extract the affected node so its current state 00707 // can be stored in the history 00708 lastAction->setShape( &((*((GlacierLine*)(mXYSet[lndx])))[nndx]) ) ; 00709 // restore the line to its original position relative to the image 00710 restoreMovedLineNode(lndx, nndx, originalNode) ; 00711 // push history element to the other history stack 00712 historyRedo->push(lastAction) ; 00713 } 00714 break ; 00715 00716 case (brokeLine): 00717 if (mHistory.size() == 0) { 00718 return ; 00719 } 00720 if (lastAction->getShape() != NULL) { 00721 // get information about the other half of the broken line 00722 GlacierLineHistoryElement * lastAction2 = historyUndo->peek() ; 00723 00724 if (lastAction2->getAction() == brokeLine) { 00725 historyUndo->pop() ; 00726 lastAction->setAction(joinedLines) ; 00727 lastAction2->setAction(joinedLines) ; 00728 historyRedo->push(lastAction2) ; 00729 historyRedo->push(lastAction) ; 00730 00731 // the first line is the new line created from the broken original 00732 // get information about what lines and nodes use to mend broken line 00733 int lndx1 = lastAction->getLineIndex() ; // line 1 index 00734 //int nndx1 = lastAction->getNodeIndex() ; // node index where line was broken 00735 00736 // the second line is the original line 00737 int lndx2 = lastAction2->getLineIndex() ; // line 2 index 00738 //int nndx2 = lastAction2->getNodeIndex() ; // node index where line was broken 00739 GlacierLine originalLine = *((GlacierLine*)lastAction2->getShape()) ; //original line stored in history 00740 00741 // join the two lines back to the original single line 00742 rejoinLine(originalLine, lndx2, lndx1, lastAction2, lastAction) ; 00743 00744 } 00745 else { 00746 historyRedo->push(lastAction) ; 00747 } 00748 } 00749 break ; 00750 00751 case (joinedLines): 00752 if (mHistory.size() == 0) { 00753 return ; 00754 } 00755 00756 if (lastAction->getShape() != NULL) { 00757 00758 // get information about the other original line 00759 GlacierLineHistoryElement * lastAction2 = historyUndo->peek() ; 00760 00761 if (lastAction2->getAction() == joinedLines) { 00762 00763 // remove the second part of this history from the stack 00764 historyUndo->pop() ; 00765 lastAction->setAction(brokeLine) ; 00766 lastAction2->setAction(brokeLine) ; 00767 // push the history elements in reverse order onto the other 00768 // stack so they maintain their relative order 00769 historyRedo->push(lastAction2) ; 00770 historyRedo->push(lastAction) ; 00771 00772 // get a copy of the original line 00773 GlacierLine restoreLine1 = *((GlacierLine*)lastAction->getShape()) ; 00774 // get information about what lines and nodes use to break a pair of joined lines 00775 int lndx1 = lastAction->getLineIndex() ; // line 1 index 00776 00777 // get a copy of the original line 00778 GlacierLine restoreLine2 = *((GlacierLine*)lastAction2->getShape()) ; 00779 // get information about what lines and nodes use to break a pair of joined lines 00780 int lndx2 = lastAction2->getLineIndex() ; // line 1 index 00781 00782 // restore the lines back to their original separation 00783 restoreJoinedLines(restoreLine2, lndx2, restoreLine1, lndx1, lastAction2, lastAction) ; 00784 00785 } 00786 else { 00787 historyRedo->push(lastAction) ; 00788 } 00789 } 00790 break ; 00791 00792 case (selection): 00793 historyRedo->push(lastAction) ; 00794 break ; 00795 00796 default : 00797 historyRedo->push(lastAction) ; 00798 break ; 00799 } // end switch on action 00800 } // end if lastAction != NULL 00801 00802 // restore previous selection of nodes/lines onscreen from 00803 // selection set undo history 00804 if ( selSetUndo->size() > 0 ) { 00805 mSelSet.clear(); 00806 mSelSet = selSetUndo->top(); 00807 selSetRedo->push(mSelSet); 00808 selSetUndo->pop(); 00809 } 00810 } 00811 00821 void GLIMSLineData::push( ) { 00822 // save undo information for current selection of nodes/lines onscreen 00823 // mUndoSel.push( mSelSet ); 00824 emit datasetChanged(); 00825 } 00826 00827 void GLIMSLineData::pushSelection( ) { 00828 mUndoSel.push( mSelSet ); 00829 Node saveNode ; 00830 mHistory.push(saveNode, -1, -1, selection) ; 00831 mRedoHistory.clear() ; 00832 } 00833 00834 00835 void GLIMSLineData::setLDF( int iline, int ildf ) { 00836 if ( iline < 0 || iline >= (int)mXYSet.size() || 00837 ildf < 0 || ildf >= (int)mLDFSet.size() ) 00838 return; 00839 00840 Shape &xys = *mXYSet[iline]; 00841 Shape &lls = *mLLSet[iline]; 00842 GlacierLine &xyline = dynamic_cast<GlacierLine&>( xys ); 00843 GlacierLine &llline = dynamic_cast<GlacierLine&>( lls ); 00844 xyline.mLDF = ildf; 00845 llline.mLDF = ildf; 00846 DspAttr &attr = xyline.getAttr(); 00847 attr.color = GLIMSGlobals::AVAILCOLORS[ mLDFSet[ildf].mColor ]; 00848 attr.style = (Qt::PenStyle)mLDFSet[ildf].mStyle; 00849 attr.width = mLDFSet[ildf].mWidth; 00850 emit datasetChanged(); 00851 } 00852 00853 void GLIMSLineData::setGID( int iline, int igid ) { 00854 if ( iline < 0 || iline >= (int)mXYSet.size() ) 00855 return; 00856 00857 // get the Shape at index iline 00858 Shape &xys = *mXYSet[iline]; 00859 Shape &lls = *mLLSet[iline]; 00860 00861 // cast the Shape to a GlacierLine 00862 GlacierLine &xyline = dynamic_cast<GlacierLine&>( xys ); 00863 GlacierLine &llline = dynamic_cast<GlacierLine&>( lls ); 00864 00865 // assign the GID (igid) to the line 00866 xyline.mGID = igid; 00867 llline.mGID = igid; 00868 00869 // announce a change 00870 emit datasetChanged(); 00871 } 00872 00873 void GLIMSLineData::addLineSetLL( std::vector<GlacierLine> &glset ) { 00874 GlacierLine *newXYLine; 00875 GlacierLine *newLLLine; 00876 00877 push(); 00878 for ( int iline=0; iline < (int)glset.size(); iline++ ) { 00879 newXYLine = new GlacierLine; 00880 newLLLine = new GlacierLine; 00881 *newXYLine = glset[iline]; 00882 *newLLLine = glset[iline]; 00883 00884 /* 00885 std::vector<Node> &ns = glset[iline].nodeset(); 00886 for( int in=0; in < (int)ns.size(); in++ ) 00887 { 00888 Node *n = new Node; 00889 *n = ns[in]; 00890 newLine->nodeset().push_back( *n ); 00891 delete n; 00892 } 00893 */ 00894 00895 mXYSet.push_back( newXYLine ); 00896 mLLSet.push_back( newLLLine ); 00897 } 00898 transformDataset(); 00899 } 00900 00901 bool GLIMSLineData::validate (ValidationReport * valRep) { 00902 bool dataValid = true ; 00903 mSelSet.clear() ; 00904 std::stringstream rptstream ; 00905 valRep->breakBegin( "Line data check..." ) ; 00906 00907 00908 // Only run line checks if there are lines to check 00909 if ( !mLLSet.size() ) { 00910 valRep->reportWarning("No lines have been created!") ; 00911 valRep->breakEnd( "CHECK COMPLETE: There are no lines to check." ) ; 00912 } 00913 else { 00914 unsigned int iline = 0 ; 00915 00916 // ------------------------------------------------------ 00917 // Check that each line is long enough 00918 // ------------------------------------------------------ 00919 valRep->subsectionBegin("Checking line vertex count.") ; 00920 for ( iline = 0 ; iline < mLLSet.size() ; iline++ ) { 00921 // get the line to check 00922 GlacierLine &llline = dynamic_cast<GlacierLine&>( *mLLSet[iline] ); 00923 00924 int lineVerts = llline.nodeset().size() ; 00925 // if line isn't long enough 00926 if ( lineVerts < 4 ) { 00927 dataValid = false ; 00928 SelectionSet::SelObj selobj ; 00929 selobj.obj = iline ; 00930 mSelSet.add( selobj ) ; 00931 00932 rptstream << "Line " << iline << " does not have enough vertices (total count of " << lineVerts << ")." << endl ; 00933 valRep->reportError( rptstream.str() ) ; 00934 rptstream.str("") ; 00935 } 00936 } 00937 valRep->subsectionEnd("Line vertex count finished.") ; 00938 00939 // ------------------------------------------------------ 00940 // Check that each line has an associated glacier ID 00941 // ------------------------------------------------------ 00942 valRep->subsectionBegin("Checking for associated glacier IDs") ; 00943 for ( iline = 0 ; iline < mLLSet.size() ; iline++ ) { 00944 // get the line to check 00945 GlacierLine &llline = dynamic_cast<GlacierLine&>( *mLLSet[iline] ); 00946 00947 // if line doesn't have a GID, add to selection 00948 if ( llline.mGID < 0 ) { 00949 dataValid = false ; 00950 SelectionSet::SelObj selobj ; 00951 selobj.obj = iline ; 00952 mSelSet.add( selobj ) ; 00953 00954 rptstream << "Line " << iline << " has no associated glacier ID" << endl ; 00955 valRep->reportError( rptstream.str() ) ; 00956 rptstream.str("") ; 00957 } 00958 } 00959 rptstream.str ("") ; 00960 valRep->subsectionEnd("Associated glacier ID check finished.") ; 00961 00962 // ------------------------------------------------------ 00963 // Check that each line has an associated line definition 00964 // ------------------------------------------------------ 00965 valRep->subsectionBegin("Checking for associated line definitions") ; 00966 for ( iline = 0 ; iline < mLLSet.size() ; iline++ ) { 00967 // get the line to check 00968 GlacierLine &llline = dynamic_cast<GlacierLine&>( *mLLSet[iline] ); 00969 00970 // if line doesn't have a GID, add to selection 00971 if ( llline.mLDF < 0 ) { 00972 dataValid = false ; 00973 SelectionSet::SelObj selobj ; 00974 selobj.obj = iline ; 00975 mSelSet.add( selobj ) ; 00976 00977 rptstream << "Line " << iline << " has no associated line definition" << endl ; 00978 valRep->reportError( rptstream.str() ) ; 00979 rptstream.str("") ; 00980 } 00981 } 00982 valRep->subsectionEnd("Associated line definition check finished.") ; 00983 00984 // ------------- 00985 // End of the line report 00986 00987 if (dataValid) { 00988 valRep->breakEnd( "CHECK COMPLETE: All lines have required information." ) ; 00989 } 00990 else { 00991 valRep->breakEnd( "ERROR: There are lines missing information. These lines are highlighted on the screen." ) ; 00992 } 00993 } 00994 00995 00996 // ------------------------------------------------------ 00997 // Check line definitions 00998 // ------------------------------------------------------ 00999 valRep->breakBegin("Checking line definition validity") ; 01000 bool linedefValid = mLDFSet.validate (valRep) ; 01001 valRep->breakEnd("Line definition validity check finished.") ; 01002 01003 01004 // ------------------------------------------------------ 01005 // Wrap up the line report 01006 // ------------------------------------------------------ 01007 if (linedefValid) { 01008 valRep->breakEnd( "CHECK COMPLETE: All line definitions have required information." ) ; 01009 } 01010 else { 01011 valRep->breakEnd( "ERROR: There are line definitions missing required information. Review the line definitions in the Line Config in the Configuration Tool." ) ; 01012 } 01013 01014 01015 // return status of lines 01016 return dataValid && linedefValid ; 01017 } 01018 01019 01020
Home |
Search |
Disclaimers & Privacy |
Contact Us GLIMSView Maintainer: dsoltesz@usgs.gov |