00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <string>
00025 #include <iostream>
00026 #include <list>
00027
00028 #ifdef WIN32
00029 #include <io.h>
00030 #else
00031 #include <unistd.h>
00032 #endif
00033
00034 using namespace std;
00035
00036 #include "TeDriverBNA.h"
00037 #include "../kernel/TeTable.h"
00038 #include "../kernel/TeGeometry.h"
00039 #include "../kernel/TeAsciiFile.h"
00040 #include "../kernel/TeException.h"
00041 #include "../kernel/TeProjection.h"
00042 #include "../kernel/TeAttribute.h"
00043 #include "../kernel/TeTable.h"
00044 #include "../kernel/TeAssertions.h"
00045 #include "../kernel/TeUtils.h"
00046 #include "../kernel/TeLayer.h"
00047 #include "../kernel/TeGeometryAlgorithms.h"
00048 #include "../kernel/TeDatabase.h"
00049
00050 bool TeReadBNAObjects(TeAsciiFile& bnaFile, TeTable& attTable, TePointSet& ptSet,
00051 TeLineSet& lnSet, TePolygonSet& pSet,
00052 int ncolumns, int nrecords, int delta, int attLinkColumnIndex);
00053
00054 bool TeBNARegionDecode(TeAsciiFile& bnaFile, TePolygonSet& temp, string& index, const int& npoints);
00055
00056 bool TeBNALineDecode(TeAsciiFile& bnaFile, TeLineSet& temp, string& index, const int& npoints);
00057
00058 bool TeBNAPointDecode(TeAsciiFile& bnaFile, TePointSet& temp, string& index);
00059
00060
00061
00062 TeLayer* TeImportBNA(const string& bnaFileName, TeDatabase* db, const string& layerName, const std::string& linkName)
00063 {
00064 if(!db || bnaFileName.empty())
00065 return 0;
00066
00067
00068 string filePrefix = TeGetName(bnaFileName.c_str());
00069 string ftest = filePrefix + ".bna";
00070 if(access(ftest.c_str(),04) == -1)
00071 {
00072 ftest = filePrefix + ".BNA";
00073 if (access(ftest.c_str(),04) == -1)
00074 return 0;
00075 }
00076
00077
00078 string lName = layerName;
00079
00080 if(layerName.empty())
00081 lName = TeGetBaseName(bnaFileName.c_str());
00082
00083 string newLayerName = lName;
00084
00085 TeLayerMap& layerMap = db->layerMap();
00086 TeLayerMap::iterator it;
00087
00088 bool flag = true;
00089
00090 int n = 1;
00091
00092 while(flag)
00093 {
00094 for(it = layerMap.begin(); it != layerMap.end(); ++it)
00095 {
00096 if(TeStringCompare(it->second->name(), newLayerName))
00097 break;
00098 }
00099
00100 if(it == layerMap.end())
00101 flag = 0;
00102 else
00103 newLayerName = lName + "_" + Te2String(n);
00104
00105 n++;
00106 }
00107
00108
00109 TeLayer* newLayer = new TeLayer(newLayerName, db);
00110
00111 if(newLayer->id() <= 0)
00112 return 0;
00113
00114 TeAttributeList attList;
00115
00116 std::string tableName = "";
00117 std::string linkNameCopy = linkName;
00118 bool res = TeImportBNA(newLayer, bnaFileName, tableName, attList, 60, linkNameCopy);
00119
00120 if (res)
00121 return newLayer;
00122 else
00123 {
00124 db->deleteLayer(newLayer->id());
00125
00126 delete newLayer;
00127
00128 return 0;
00129 }
00130 }
00131
00132 bool TeImportBNA(TeLayer* layer, const string& bnaFileName, string attrTableName,
00133 TeAttributeList& attList, int unsigned chunkSize, std::string& linkName)
00134 {
00135 if(chunkSize <= 0)
00136 chunkSize = 1;
00137
00138
00139 char separator = ',';
00140
00141
00142 if(!TeReadBNAAttributeList(bnaFileName, attList))
00143 return false;
00144
00145 bool autoIndex = true;
00146 int linkIndex = -1;
00147 unsigned int count = 0;
00148 int ncol = attList.size();
00149 if(linkName.empty())
00150 {
00151 linkName = "object_id_" + Te2String(layer->id());
00152 std::string s2 = TeConvertToUpperCase(linkName);
00153 while(true)
00154 {
00155 unsigned int j = 0;
00156 for (j=0; j<attList.size(); j++)
00157 {
00158 string s0 = attList[j].rep_.name_;
00159 string s1 = TeConvertToUpperCase(s0);
00160 if ( s1 == s2)
00161 {
00162 break;
00163 }
00164 }
00165 if(j < attList.size())
00166 {
00167 ++count;
00168 linkName = "object_id_" + Te2String(count);
00169 }
00170 else
00171 {
00172 break;
00173 }
00174 }
00175
00176 TeAttribute at;
00177 at.rep_.type_ = TeSTRING;
00178 at.rep_.numChar_ = 16;
00179 at.rep_.name_ = linkName;
00180 at.rep_.isPrimaryKey_ = true;
00181 attList.push_back(at);
00182 linkIndex = attList.size()-1;
00183 autoIndex = true;
00184 }
00185 else
00186 {
00187 unsigned int j = 0;
00188
00189 TeAttributeList::iterator it = attList.begin();
00190 while (it != attList.end())
00191 {
00192 if (TeConvertToUpperCase((*it).rep_.name_) == TeConvertToUpperCase(linkName))
00193 {
00194 if ((*it).rep_.type_ != TeSTRING)
00195 {
00196 (*it).rep_.type_ = TeSTRING;
00197 (*it).rep_.numChar_ = 16;
00198 }
00199 (*it).rep_.isPrimaryKey_ = true;
00200 linkIndex = j;
00201 break;
00202 }
00203 ++it;
00204 ++j;
00205 }
00206 if (it == attList.end())
00207 {
00208 linkName = "object_id_" + Te2String(layer->id());;
00209 while(true)
00210 {
00211 for(j=0; j<attList.size(); j++)
00212 {
00213 if (TeConvertToUpperCase(attList[j].rep_.name_) == TeConvertToUpperCase(linkName))
00214 {
00215 break;
00216 }
00217 }
00218 if(j < attList.size())
00219 {
00220 ++count;
00221 linkName = "object_id_" + Te2String(count);
00222 }
00223 else
00224 {
00225 break;
00226 }
00227 }
00228 TeAttribute at;
00229 at.rep_.type_ = TeSTRING;
00230 at.rep_.numChar_ = 16;
00231 at.rep_.name_ = linkName;
00232 at.rep_.isPrimaryKey_ = true;
00233 attList.push_back(at);
00234 autoIndex = true;
00235 }
00236 }
00237
00238
00239 if (attrTableName.empty())
00240 {
00241 if (layer->name().empty())
00242 return false;
00243 else
00244 attrTableName = layer->name();
00245 }
00246
00247 TeTable attTable(attrTableName, attList, linkName, linkName, TeAttrStatic);
00248
00249 attTable.setSeparator(separator);
00250
00251
00252 if(!layer->createAttributeTable(attTable))
00253 {
00254 return false;
00255 }
00256
00257 TeAsciiFile bnaFile(bnaFileName);
00258
00259 int delta = 0;
00260
00261 TePointSet ptSet;
00262 TeLineSet lnSet;
00263 TePolygonSet pSet;
00264
00265 while(TeReadBNAObjects(bnaFile, attTable, ptSet, lnSet, pSet, ncol, chunkSize, delta, linkIndex))
00266 {
00267
00268 if (!layer->saveAttributeTable( attTable ))
00269 {
00270 attTable.clear();
00271 break;
00272 }
00273
00274
00275 if(ptSet.size() > 0)
00276 {
00277 layer->addPoints(ptSet);
00278 ptSet.clear();
00279 }
00280
00281 if(lnSet.size() > 0)
00282 {
00283 layer->addLines(lnSet);
00284 lnSet.clear();
00285 }
00286
00287 if(pSet.size() > 0)
00288 {
00289 layer->addPolygons(pSet);
00290 pSet.clear();
00291 }
00292
00293 delta += attTable.size();
00294
00295 attTable.clear();
00296 }
00297
00298
00299 int rep = layer->geomRep();
00300 if (rep & TePOINTS)
00301 {
00302 layer->database()->insertMetadata(layer->tableName(TePOINTS),layer->database()->getSpatialIdxColumn(TePOINTS), 0.0005,0.0005,layer->box());
00303 layer->database()->createSpatialIndex(layer->tableName(TePOINTS),layer->database()->getSpatialIdxColumn(TePOINTS), (TeSpatialIndexType)TeRTREE);
00304 }
00305 if (rep & TeLINES)
00306 {
00307 layer->database()->insertMetadata(layer->tableName(TeLINES),layer->database()->getSpatialIdxColumn(TeLINES), 0.0005,0.0005,layer->box());
00308 layer->database()->createSpatialIndex(layer->tableName(TeLINES),layer->database()->getSpatialIdxColumn(TeLINES), (TeSpatialIndexType)TeRTREE);
00309 }
00310 if (rep & TePOLYGONS)
00311 {
00312 layer->database()->insertMetadata(layer->tableName(TePOLYGONS),layer->database()->getSpatialIdxColumn(TePOLYGONS), 0.0005,0.0005,layer->box());
00313 layer->database()->createSpatialIndex(layer->tableName(TePOLYGONS),layer->database()->getSpatialIdxColumn(TePOLYGONS), (TeSpatialIndexType)TeRTREE);
00314 }
00315 return true;
00316 }
00317
00318
00319 bool TeReadBNAAttributeList(const string& bnaFileName, TeAttributeList& attList)
00320 {
00321 TeAsciiFile bnaFile(bnaFileName);
00322
00323 if(!bnaFile.isNotAtEOF())
00324 return false;
00325
00326 vector<string> strList;
00327
00328 bnaFile.readStringListCSV(strList, ',');
00329
00330 unsigned int nFields = (strList.size() - 1u);
00331
00332 if(nFields <= 0)
00333 return false;
00334
00335 if(attList.size() > 0u)
00336 {
00337 if(attList.size() != nFields)
00338 return false;
00339 else
00340 return true;
00341 }
00342
00343
00344
00345
00346 TeAttribute at1;
00347 at1.rep_.type_ = TeSTRING;
00348 at1.rep_.numChar_ = 255;
00349 at1.rep_.name_ = "IBGE_CODE";
00350 at1.rep_.isPrimaryKey_ = false;
00351 attList.push_back(at1);
00352
00353 if(nFields > 1)
00354 {
00355 TeAttribute at2;
00356 at2.rep_.type_ = TeSTRING;
00357 at2.rep_.numChar_ = 255;
00358 at2.rep_.name_ = "IBGE_NAME";
00359 at2.rep_.isPrimaryKey_ = false;
00360 attList.push_back(at2);
00361 }
00362
00363 for(unsigned int i = 2; i < nFields; ++i)
00364 {
00365 TeAttribute at;
00366 at.rep_.type_ = TeSTRING;
00367 at.rep_.numChar_ = 255;
00368 at.rep_.name_ = string("FIELD_") + Te2String(i);
00369 at.rep_.isPrimaryKey_ = false;
00370 attList.push_back(at);
00371 }
00372
00373 return true;
00374 }
00375
00376
00377 bool TeReadBNAObjects(TeAsciiFile& bnaFile, TeTable& attTable, TePointSet& ptSet,
00378 TeLineSet& lnSet, TePolygonSet& pSet,
00379 int ncolumns, int nrecords, int delta , int attLinkColumnIndex)
00380 {
00381 if (!bnaFile.isNotAtEOF() || nrecords <=0 || ncolumns <= 0)
00382 return false;
00383
00384 char separator = attTable.separator();
00385
00386 int count;
00387
00388 for(count=0; count < nrecords; ++count)
00389 {
00390 if(!bnaFile.isNotAtEOF())
00391 break;
00392
00393
00394
00395 TeTableRow row;
00396 for(int n = 0; n < ncolumns; ++n)
00397 {
00398 std::string value;
00399
00400 try
00401 {
00402 value = bnaFile.readStringCSVNoQuote(separator);
00403 }
00404 catch(...)
00405 {
00406 if(count > 0)
00407 return true;
00408 else
00409 return false;
00410 }
00411
00412 row.push_back (value);
00413 }
00414
00415 if(attLinkColumnIndex == row.size())
00416 {
00417 row.push_back(Te2String(delta));
00418 }
00419 attTable.add(row);
00420
00421 string bnaGeometryTypeLen = bnaFile.readStringCSVNoQuote(separator);
00422
00423 int bnaGTypeLen = atoi(bnaGeometryTypeLen.c_str());
00424
00425 std::string index = row[attLinkColumnIndex];
00426
00427
00428 bnaFile.findNewLine();
00429
00430 if(bnaGTypeLen > 2)
00431 {
00432 if(!TeBNARegionDecode(bnaFile, pSet, index, bnaGTypeLen))
00433 return false;
00434 }
00435 else if(bnaGTypeLen < -1)
00436 {
00437 if(!TeBNALineDecode(bnaFile, lnSet, index, -bnaGTypeLen))
00438 return false;
00439 }
00440 else if(bnaGTypeLen == 1)
00441 {
00442 if(!TeBNAPointDecode(bnaFile, ptSet, index))
00443 return false;
00444 }
00445 else
00446 return false;
00447
00448 ++delta;
00449 bnaFile.findNewLine();
00450 }
00451
00452 return true;
00453 }
00454
00455 bool TeBNARegionDecode(TeAsciiFile& bnaFile, TePolygonSet& temp, string& index, const int& npoints)
00456 {
00457 int i;
00458 unsigned int j;
00459
00460 vector<TePolygon> pVec;
00461 TeLine2D l;
00462
00463 TeCoord2D coordMainArea;
00464 TeCoord2D firstCoord;
00465 bool first = false;
00466
00467 for(i = 0; i < npoints; ++i)
00468 {
00469 if(!bnaFile.isNotAtEOF())
00470 return false;
00471
00472 double x = bnaFile.readFloat();
00473 bnaFile.readChar();
00474 double y = bnaFile.readFloat();
00475
00476
00477
00478 TeCoord2D c(x, y);
00479
00480 if(i == 0)
00481 {
00482 coordMainArea.setXY(x, y);
00483 firstCoord = coordMainArea;
00484 first = false;
00485 l.add(c);
00486 }
00487 else
00488 {
00489 if(c == firstCoord)
00490 {
00491 l.add(c);
00492 l.objectId(index);
00493 TeLinearRing r(l);
00494 r.objectId(index);
00495 TePolygon p;
00496 p.add(r);
00497 p.objectId(index);
00498
00499 if(pVec.size() == 0)
00500 pVec.push_back(p);
00501 else
00502 {
00503 for(j = 0; j < pVec.size(); ++j)
00504 {
00505 TePolygon paux = pVec[j];
00506 if(TeWithin(p, paux))
00507 {
00508 pVec[j].add(p[0]);
00509 break;
00510 }
00511
00512 }
00513
00514 if(j == pVec.size())
00515 pVec.push_back(p);
00516 }
00517
00518
00519 l = TeLine2D();
00520
00521 first = true;
00522
00523 }
00524 else if(c == coordMainArea)
00525 {
00526 continue;
00527 }
00528 else
00529 {
00530 if(first)
00531 {
00532 firstCoord = c;
00533 first = false;
00534 }
00535
00536 l.add(c);
00537 }
00538 }
00539 }
00540
00541 for(unsigned int k = 0; k < pVec.size(); ++k)
00542 temp.add(pVec[k]);
00543
00544
00545 return true;
00546 }
00547
00548 bool TeBNALineDecode(TeAsciiFile& bnaFile, TeLineSet& temp, string& index, const int& npoints)
00549 {
00550 TeLine2D l;
00551
00552 l.objectId(index);
00553
00554 for(int i = 0; i < npoints; ++i)
00555 {
00556 if(!bnaFile.isNotAtEOF())
00557 return false;
00558
00559 double x = bnaFile.readFloat();
00560 bnaFile.readChar();
00561 double y = bnaFile.readFloat();
00562
00563
00564
00565 TeCoord2D c(x, y);
00566
00567 l.add(c);
00568 }
00569
00570 temp.add(l);
00571
00572 return true;
00573 }
00574
00575 bool TeBNAPointDecode(TeAsciiFile& bnaFile, TePointSet& temp, string& index)
00576 {
00577 if(!bnaFile.isNotAtEOF())
00578 return false;
00579
00580 double x = bnaFile.readFloat();
00581 bnaFile.readChar();
00582 double y = bnaFile.readFloat();
00583
00584
00585
00586 TeCoord2D c(x, y);
00587
00588 TePoint pt(c);
00589
00590 pt.objectId(index);
00591
00592 temp.add(pt);
00593
00594 return true;
00595 }