TNB Library
TnbShapeFile.h
[詳解]
1#pragma once
11#include "TnbPointerVector.h"
12#include "TnbLikenMemToFile.h"
13#include "TnbDBaseFile.h"
14
15
16
17//TNB Library
18namespace TNB
19{
20
21
22
68class CShapeFile : public CDBaseFile
69{
70 DEFSUPER(CDBaseFile);
71public:
72
73 typedef long Integer;
74 typedef double Double;
75
76 #pragma pack(push)
77 #pragma pack(1)
78
86 {
87 public:
92 CBeInteger(Integer l = 0) : m_value(m_SwapEndian(l))
93 {
94 }
99 operator Integer() const
100 {
101 return m_SwapEndian(m_value);
102 }
109 {
110 m_value = m_SwapEndian(l);
111 return l;
112 }
113 private:
114 // エンディアン変換
115 Integer m_SwapEndian(Integer l) const
116 {
117 return SwapEndian(DWORD(l));
118 }
119 Integer m_value;
120 };
121
127 {
138 {
139 Zero(*this);
140 }
141 };
142
148 struct THead
149 {
157 THead(void) : fileCode(9994), version(1000), shapeType(0)
158 {
159 }
160 };
161
162 #pragma pack(pop)
163
171 {
173 virtual ~IRecordContent(void) {}
178 virtual Integer GetShapeType(void) const = 0;
185 virtual size_t Write(IWriter& _w) const = 0;
192 virtual void Read(const IReader& r, size_t size) = 0;
197 virtual CStr ToString(void) const = 0;
198 };
199
205 {
206 public:
211 virtual Integer GetShapeType(void) const
212 {
213 return 0; //Null Shape
214 }
221 virtual size_t Write(IWriter& _w) const
222 {
223 return 0;
224 }
231 virtual void Read(const IReader& r, size_t size)
232 {
233 }
238 virtual CStr ToString(void) const
239 {
240 return _T("Null Shape");
241 }
242 };
243
249 {
250 public:
256 {
257 }
263 {
264 return m_data;
265 }
270 virtual Integer GetShapeType(void) const
271 {
272 return m_type;
273 }
280 virtual size_t Write(IWriter& _w) const
281 {
282 _w.WriteFrom(m_data);
283 return m_data.GetSize();
284 }
291 virtual void Read(const IReader& r, size_t size)
292 {
293 m_data = r.ReadExactly(size);
294 }
299 virtual CStr ToString(void) const
300 {
301 return CStr::Fmt(_T("ShapeType.%d , len = %d"), m_type, m_data.GetSize());
302 }
303 private:
304 Integer m_type;
305 CByteVector m_data;
306 };
307
308
309 //--------
310
311
314 {
315 }
316
322 {
323 m_shapeHead.shapeType = type;
324 }
325
331 {
332 return m_shapeHead.shapeType;
333 }
334
340 {
341 m_shapeHead.bb = bb;
342 }
343
348 const TBoundingBox& GetBoundingBox(void) const
349 {
350 return m_shapeHead.bb;
351 }
352
359 {
360 m_shapeRecords.RemoveAll();
361 return _super::AllDeleteRecord();
362 }
363
371 INDEX AddRecord(void)
372 {
373 INDEX r1 = _super::AddRecord();
374 INDEX r2 = m_shapeRecords.Add(new CNullShapeRecordContent());
375 ASSERT( r1 == r2 );
376 return r1;
377 }
378
386 bool InsertRecord(INDEX record)
387 {
388 bool r1 = _super::InsertRecord(record);
389 bool r2 = m_shapeRecords.Insert(record, new CNullShapeRecordContent());
390 ASSERT( r1 == r2 );
391 return r1;
392 }
393
400 bool DeleteRecord(INDEX record)
401 {
402 bool r1 = _super::DeleteRecord(record);
403 bool r2 = m_shapeRecords.Remove(record);
404 ASSERT( r1 == r2 );
405 return r1;
406 }
407
415 bool SetShapeRecord(INDEX record, IRecordContent* P)
416 {
417 return m_shapeRecords.Set(record, P);
418 }
419
426 const IRecordContent* GetShapeRecord(INDEX record) const
427 {
428 return m_shapeRecords.Get(record);
429 }
430
440 bool LoadFile(LPCTSTR lpszBaseFileName, bool withTypeCheck = true)
441 {
443 CStr mainFn;
444 CStr indexFn;
445 CStr attrFn;
446 m_MakeFileName(mainFn, indexFn, attrFn, lpszBaseFileName);
447 CFileReader mainRf;
448 CFileReader indexRf;
449 Integer oldType = GetHeadShapeType();
450 if ( mainRf.Open(mainFn) && indexRf.Open(indexFn) )
451 {
452 try
453 {
454 m_LoadMain(mainRf);
455 }
456 catch ( CTnbException& e )
457 {
458 e.OnCatch();
459 _super::AllDeleteRecord();
460 return false;
461 }
462 catch ( ... )
463 {
464 throw;
465 }
466 bool r = _super::LoadFile(attrFn);
467 //
468 if ( r )
469 {
470 if ( withTypeCheck && oldType != GetHeadShapeType() )
471 {
472 TRACE2(" メインファイルのタイプ[%d]と現在のタイプ[%d]が一致していません!\n", GetHeadShapeType(), oldType);
473 SetHeadShapeType(oldType);
474 _super::AllDeleteRecord();
475 r = false;
476 }
477 else if ( _super::GetRecordCount() != m_shapeRecords.GetSize() )
478 {
479 TRACE0(" メインファイルと属性ファイルのレコードの数が一致していません!\n" );
480 _super::AllDeleteRecord();
481 r = false;
482 }
483 }
484 //
485 return r;
486 }
487 return false;
488 }
489
498 bool SaveFile(LPCTSTR lpszBaseFileName) const
499 {
500 CStr mainFn;
501 CStr indexFn;
502 CStr attrFn;
503 m_MakeFileName(mainFn, indexFn, attrFn, lpszBaseFileName);
504 CFileWriter mainWf;
505 CFileWriter indexWf;
506 if ( mainWf.New(mainFn) && indexWf.New(indexFn) )
507 {
508 try
509 {
510 m_SaveMain(mainWf, indexWf);
511 }
512 catch ( CTnbException& e )
513 {
514 e.OnCatch();
515 return false;
516 }
517 catch ( ... )
518 {
519 throw;
520 }
521 bool r = _super::SaveFile(attrFn);
522 //
523 return r;
524 }
525 return false;
526 }
527
528protected:
529
538 virtual CShapeFile::IRecordContent* LoadType(Integer type, const IReader& r, size_t sz)
539 {
540 return NULL;
541 }
542
544 void Dump(void)
545 {
546 #ifdef _DEBUG
547 TRACE0("-- ShapeFile情報 --\n");
548 TRACE1("ShapeType %d\n", m_shapeHead.shapeType);
549 TRACE2("BoundingBox X min %g, max %g\n", m_shapeHead.bb.xMin, m_shapeHead.bb.xMax);
550 TRACE2("BoundingBox Y min %g, max %g\n", m_shapeHead.bb.yMin, m_shapeHead.bb.yMax);
551 TRACE2("BoundingBox Z min %g, max %g\n", m_shapeHead.bb.zMin, m_shapeHead.bb.zMax);
552 TRACE2("BoundingBox M min %g, max %g\n", m_shapeHead.bb.mMin, m_shapeHead.bb.mMax);
553 loop ( i, m_shapeRecords.GetSize() )
554 {
555 CStr s = m_shapeRecords[i]->ToString();
556 TRACE2("record.%d, %s\n", i + 1, s);
557 }
558 #endif //_DEBUG
559 _super::Dump();
560 }
561
562private:
563
565 void m_MakeFileName(CStr& _mainFn, CStr& _indexFn, CStr& _attrFn, LPCTSTR lpszBase) const
566 {
567 CStr base = lpszBase;
568 base.TrimRight('.');
569 base += '.';
570 _mainFn = base + _T("shp");
571 _indexFn = base + _T("shx");
572 _attrFn = base + _T("dbf");
573 }
580 void m_SaveMain(IWriter& _mainWt, IWriter& _indexWt) const
581 {
582 CLikenMemToFile dmyWt;
583 //== ヘッダを仮に追加
584 THead hd = m_shapeHead;
585 _mainWt.Write(sizeof(hd), &hd);
586 _indexWt.Write(sizeof(hd), &hd);
587 //== レコード
588 loop ( i, m_shapeRecords.GetSize() )
589 {
590 // レコードコンテンツ用意
591 Integer type = m_shapeRecords[i]->GetShapeType();
592 CBeInteger len = down_cast<CShapeFile::Integer>(sizeof(Integer) + m_shapeRecords[i]->Write(dmyWt)) / sizeof(WORD);
593 // インデックスデータ作成
594 CBeInteger ofs = static_cast<long>(_mainWt.GetSize() / sizeof(WORD));
595 _indexWt.Write(sizeof(ofs), &ofs);
596 _indexWt.Write(sizeof(len), &len);
597 // メインデータ作成
598 CBeInteger no = down_cast<CShapeFile::Integer>(i + 1);
599 _mainWt.Write(sizeof(no), &no);
600 _mainWt.Write(sizeof(len), &len);
601 _mainWt.Write(sizeof(type), &type);
602 m_shapeRecords[i]->Write(_mainWt);
603 }
604 //== ヘッダを付加する
605 hd.fileLength = static_cast<long>(_mainWt.GetSize() / sizeof(WORD));
606 _mainWt.Seek(0);
607 _mainWt.Write(sizeof(hd), &hd);
608 hd.fileLength = static_cast<long>(_indexWt.GetSize() / sizeof(WORD));
609 _indexWt.Seek(0);
610 _indexWt.Write(sizeof(hd), &hd);
611 }
616 void m_LoadMain(const IReader& r)
617 {
618 THead hd;
619 CPointerVectorT<IRecordContent> records; // レコード情報
620 r.Read(sizeof(THead), &hd);
621 if ( hd.fileCode != 9994 || hd.version != 1000 )
622 {
624 }
625 while ( r.GetLeftoverSize() > 0 )
626 {
627 CBeInteger no;
628 r.Read(sizeof(no), &no); //レコード番号
629 CBeInteger len;
630 r.Read(sizeof(len), &len); //コンテンツ長
631 Integer type;
632 r.Read(sizeof(type), &type); //シェープタイプ
633 TRACE3("RecNo.%d, Len = %d, Type = %d\n", long(no), long(len), type);
634 size_t sz = len * 2 - sizeof(type);
635 //
636 IRecordContent* P = LoadType(type, r, sz);
637 if ( P != NULL )
638 {
639 records.Add(P);
640 }
641 else if ( type == 0 )
642 {
643 CNullShapeRecordContent rc;
644 rc.Read(r, sz);
645 records.Add(new CNullShapeRecordContent(rc));
646 }
647 else
648 {
649 // その他
650 CUnknownRecordContent rc(type);
651 rc.Read(r, sz);
652 records.Add(new CUnknownRecordContent(rc));
653 }
654 }
655 m_shapeRecords = records;
656 m_shapeHead = hd;
657 }
658
659 C_ASSERT ( sizeof(Integer) == 4 ); // サイズチェック
660 C_ASSERT ( sizeof(Double) == 8 ); // サイズチェック
661 C_ASSERT ( sizeof(CBeInteger) == 4 ); // サイズチェック
662 C_ASSERT ( sizeof(THead) == 100 ); // サイズチェック
663
664 THead m_shapeHead;
665 CPointerVectorT<IRecordContent> m_shapeRecords;
666
667 friend class CShapeFileTest;
668};
669
670
671
687{
688 DEFSUPER(CShapeFile);
689public:
690
696 {
697 public:
703 CPointRecordContent(Double x = 0, Double y = 0) : m_x(x), m_y(y)
704 {
705 }
710 Double GetX(void) const { return m_x; }
715 Double GetY(void) const { return m_y; }
721 void Set(Double x, Double y) { m_x = x; m_y = y; }
726 virtual Integer GetShapeType(void) const
727 {
728 return 1; //Point
729 }
736 virtual size_t Write(IWriter& _w) const
737 {
738 _w.Write(sizeof(m_x), &m_x);
739 _w.Write(sizeof(m_y), &m_y);
740 return sizeof(Double) * 2;
741 }
748 virtual void Read(const IReader& r, size_t size)
749 {
750 if ( size < sizeof(m_x) * 2 )
751 {
753 }
754 r.ReadExactly(sizeof(m_x), &m_x);
755 r.ReadExactly(sizeof(m_y), &m_y);
756 }
761 virtual CStr ToString(void) const
762 {
763 return CStr::Fmt(_T("Point x = %g, y = %g"), m_x, m_y);
764 }
765 private:
766 Double m_x;
767 Double m_y;
768 };
769
770
771 //------------------------------
772
773
776 {
778 }
779
788 bool SetPointShapeRecord(INDEX record, Double x, Double y)
789 {
791 if ( ! SetShapeRecord(record, P) )
792 {
793 delete P;
794 return false;
795 }
797 return true;
798 }
799
806 const CPointRecordContent* GetPointShapeRecord(INDEX record) const
807 {
808 const IRecordContent* P = GetShapeRecord(record);
809 if ( P != NULL && P->GetShapeType() == 1 )
810 {
811 return static_cast<const CPointRecordContent*>(P);
812 }
813 return NULL;
814 }
815
816protected:
817
826 virtual CShapeFile::IRecordContent* LoadType(Integer type, const IReader& r, size_t sz)
827 {
828 if ( type == 1 )
829 {
831 rc.Read(r, sz);
832 return new CPointRecordContent(rc);
833 }
834 return NULL;
835 }
836};
837
838
839
840}; // TNB
841
dBaseファイル関係のヘッダ
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
ファイル関係のヘッダ
ポインタ配列管理関係のヘッダ
dBaseファイル管理クラス
Definition: TnbDBaseFile.h:45
ファイル読み込みクラス
Definition: TnbFile.h:338
bool Open(LPCTSTR lpszName, bool boIsShare=true, bool boDummy=false)
[操作] オープン
Definition: TnbFile.h:364
ファイル書き込みクラス
Definition: TnbFile.h:475
bool New(LPCTSTR lpszName, bool boIsShare=true)
[操作] 新規オープン.
Definition: TnbFile.h:501
長さ異常発生例外
Definition: TnbException.h:133
パラメータ不正例外
Definition: TnbException.h:159
ファイル風メモリ管理クラス
ポインタ配列管理テンプレート
INDEX Add(TYP *P)
[追加] 要素一つ追加
Point レコードコンテンツ
Definition: TnbShapeFile.h:696
Double GetY(void) const
[取得] Y取得.
Definition: TnbShapeFile.h:715
Double GetX(void) const
[取得] X取得.
Definition: TnbShapeFile.h:710
virtual CStr ToString(void) const
[取得] 文字列取得.
Definition: TnbShapeFile.h:761
virtual void Read(const IReader &r, size_t size)
[読込] 読込み 解析しデータを保持します。
Definition: TnbShapeFile.h:748
virtual Integer GetShapeType(void) const
[取得] シェープタイプ取得.
Definition: TnbShapeFile.h:726
CPointRecordContent(Double x=0, Double y=0)
コンストラクタ.
Definition: TnbShapeFile.h:703
void Set(Double x, Double y)
[設定] X,Y 設定.
Definition: TnbShapeFile.h:721
virtual size_t Write(IWriter &_w) const
[書出] 書出し 保持しているデータを書き出し(シェープタイプは対象外)。
Definition: TnbShapeFile.h:736
シェープファイル type Point 管理クラス
Definition: TnbShapeFile.h:687
CShapeFileTypePoint(void)
コンストラクタ
Definition: TnbShapeFile.h:775
virtual CShapeFile::IRecordContent * LoadType(Integer type, const IReader &r, size_t sz)
[通知] タイプ別読込み処理
Definition: TnbShapeFile.h:826
bool SetPointShapeRecord(INDEX record, Double x, Double y)
[設定] ポイントシェープコンテンツ設定.
Definition: TnbShapeFile.h:788
const CPointRecordContent * GetPointShapeRecord(INDEX record) const
[取得] シェープコンテンツ取得.
Definition: TnbShapeFile.h:806
ビックエンディアンINTEGER.
Definition: TnbShapeFile.h:86
Integer operator=(Integer l)
[設定] 値設定
Definition: TnbShapeFile.h:108
CBeInteger(Integer l=0)
コンストラクタ.
Definition: TnbShapeFile.h:92
NULL SHAPE レコードコンテンツ
Definition: TnbShapeFile.h:205
virtual CStr ToString(void) const
[取得] 文字列取得.
Definition: TnbShapeFile.h:238
virtual void Read(const IReader &r, size_t size)
[読込] 読込み 解析しデータを保持します。
Definition: TnbShapeFile.h:231
virtual Integer GetShapeType(void) const
[取得] シェープタイプ取得.
Definition: TnbShapeFile.h:211
virtual size_t Write(IWriter &_w) const
[書出] 書出し 保持しているデータを書き出し(シェープタイプは対象外)。
Definition: TnbShapeFile.h:221
不明 レコードコンテンツ
Definition: TnbShapeFile.h:249
virtual CStr ToString(void) const
[取得] 文字列取得.
Definition: TnbShapeFile.h:299
virtual void Read(const IReader &r, size_t size)
[読込] 読込み 解析しデータを保持します。
Definition: TnbShapeFile.h:291
virtual Integer GetShapeType(void) const
[取得] シェープタイプ取得.
Definition: TnbShapeFile.h:270
CUnknownRecordContent(Integer st)
コンストラクタ
Definition: TnbShapeFile.h:255
CByteVector & Refer(void)
[参照] データ
Definition: TnbShapeFile.h:262
virtual size_t Write(IWriter &_w) const
[書出] 書出し 保持しているデータを書き出し(シェープタイプは対象外)。
Definition: TnbShapeFile.h:280
シェープファイル管理クラス
Definition: TnbShapeFile.h:69
void Dump(void)
Traceダンプ
Definition: TnbShapeFile.h:544
double Double
符号付き64bitIEEE浮動小数点(8bytes)
Definition: TnbShapeFile.h:74
bool DeleteRecord(INDEX record)
[削除] レコード削除.
Definition: TnbShapeFile.h:400
bool SetShapeRecord(INDEX record, IRecordContent *P)
[設定] シェープコンテンツ設定.
Definition: TnbShapeFile.h:415
bool AllDeleteRecord(void)
[削除] レコード全削除.
Definition: TnbShapeFile.h:358
void SetBoundingBox(const TBoundingBox &bb)
[設定] バウンディングボックス設定.
Definition: TnbShapeFile.h:339
virtual CShapeFile::IRecordContent * LoadType(Integer type, const IReader &r, size_t sz)
[通知] タイプ別読込み処理
Definition: TnbShapeFile.h:538
long Integer
符号付き32bit整数(4bytes)
Definition: TnbShapeFile.h:73
bool InsertRecord(INDEX record)
[挿入] レコード挿入.
Definition: TnbShapeFile.h:386
const IRecordContent * GetShapeRecord(INDEX record) const
[取得] シェープコンテンツ取得.
Definition: TnbShapeFile.h:426
const TBoundingBox & GetBoundingBox(void) const
[取得] バウンディングボックス取得.
Definition: TnbShapeFile.h:348
void SetHeadShapeType(Integer type)
[設定] ヘッダシェープタイプ設定.
Definition: TnbShapeFile.h:321
CShapeFile(void)
コンストラクタ
Definition: TnbShapeFile.h:313
bool LoadFile(LPCTSTR lpszBaseFileName, bool withTypeCheck=true)
[読込] ファイル読込み 保持している情報を破棄し、ファイルから読込みます。
Definition: TnbShapeFile.h:440
Integer GetHeadShapeType(void) const
[取得] ヘッダシェープタイプ取得.
Definition: TnbShapeFile.h:330
INDEX AddRecord(void)
[追加] レコード追加.
Definition: TnbShapeFile.h:371
bool SaveFile(LPCTSTR lpszBaseFileName) const
[作成] ファイル作成.
Definition: TnbShapeFile.h:498
static CStrT Fmt(const TCHAR *lpszFormat,...)
[作成] 書式付き文字列作成
Definition: TnbStr.h:1206
CStrT & TrimRight(TYP t=' ')
[処理] 末尾から文字をトリム.
Definition: TnbStr.h:990
例外ベースクラス
Definition: TnbException.h:36
void OnCatch(void) const
[表示] 内容表示
Definition: TnbException.h:69
virtual size_t GetSize(void) const
[取得] サイズ取得
Definition: TnbVector.h:368
void Zero(V &value)
[設定] ゼロクリア.
Definition: TnbDef.h:399
WORD SwapEndian(WORD val)
[変換] エンディアン変換.
Definition: TnbDef.h:1018
TNB Library
Definition: TnbDoxyTitle.txt:2
レコードコンテンツ抽象クラス.
Definition: TnbShapeFile.h:171
virtual size_t Write(IWriter &_w) const =0
[書出] 書出し 保持しているデータを書き出し(シェープタイプは対象外)。
virtual void Read(const IReader &r, size_t size)=0
[読込] 読込み 解析しデータを保持します。
virtual CStr ToString(void) const =0
[取得] 文字列取得.
virtual Integer GetShapeType(void) const =0
[取得] シェープタイプ取得.
virtual ~IRecordContent(void)
デストラクタ
Definition: TnbShapeFile.h:173
バウンディングボックス型.
Definition: TnbShapeFile.h:127
TBoundingBox(void)
コンストラクタ
Definition: TnbShapeFile.h:137
Double mMax
Bounding Box M 最大
Definition: TnbShapeFile.h:135
Double mMin
Bounding Box M 最小
Definition: TnbShapeFile.h:134
Double zMax
Bounding Box Z 最大
Definition: TnbShapeFile.h:133
Double xMax
Bounding Box X 最大
Definition: TnbShapeFile.h:130
Double yMin
Bounding Box Y 最小
Definition: TnbShapeFile.h:129
Double zMin
Bounding Box Z 最小
Definition: TnbShapeFile.h:132
Double xMin
Bounding Box X 最小
Definition: TnbShapeFile.h:128
Double yMax
Bounding Box Y 最大
Definition: TnbShapeFile.h:131
ファイルヘッダ型.
Definition: TnbShapeFile.h:149
Integer version
バージョン
Definition: TnbShapeFile.h:153
TBoundingBox bb
バウンディングボックス
Definition: TnbShapeFile.h:155
CBeInteger fileLength
ファイル長(単位 word)
Definition: TnbShapeFile.h:152
THead(void)
コンストラクタ
Definition: TnbShapeFile.h:157
CBeInteger fileCode
ファイルコード
Definition: TnbShapeFile.h:150
CBeInteger padding[5]
未使用
Definition: TnbShapeFile.h:151
Integer shapeType
シェープタイプ
Definition: TnbShapeFile.h:154
読み込みインターフェース
Definition: TnbReader.h:36
LONGLONG GetLeftoverSize(void) const
[取得] 残りサイズ取得.
Definition: TnbReader.h:95
virtual LONGLONG Seek(LONGLONG llOffset, ESeekMode eSeek=TOP) const =0
[操作] シーク.
virtual size_t Read(size_t size, LPVOID _P) const =0
[取得] 読み込み
void ReadExactly(size_t size, LPVOID _P) const
[取得] 読み込み.
Definition: TnbReader.h:114
virtual LONGLONG GetSize(void) const =0
[取得] サイズ取得
書き込みインターフェース
Definition: TnbWriter.h:36
void WriteFrom(const IConstCollectionT< BYTE > &c)
[保存] 書き込み.
Definition: TnbWriter.h:65
virtual void Write(size_t size, LPCVOID P)=0
[保存] 書き込み