Maps > Rogue Wave Views リーダー・フレームワーク > 機能イテレーター > 新しいリーダーの作成
 
新しいリーダーの作成
このセクションには IlvMapFeatureIterator の例があり、これを使って ASCII ファイルに保存されているポリラインを読み込むことができます。
メモ: IlvMapFeatureIterator 抽象クラスを実装するクラスは、必ずしもファイル・リーダーとは限りません。たとえば、マップ・サーバーへの問い合わせ結果について反復処理が行えます。
読み込むファイル
読み込む ASCII ファイルは、特にこの例のために作成されています。その形式は非常に単純で、仕様は以下のとおりです。
*このファイルには、形式を特定するヘッダーがあります。
*1 行ごとに 1 組の座標 (緯度と経度) があります。これらの座標は度単位で表されます。
*行にコメントが含まれている場合があります。コメントがある場合、それらのコメントはマージされてアトリビュートになります。
*ポリラインは空白行で分離されています。
*ファイルには、.pol 拡張子が付いています。
以下は ASCII ファイルです。
#ascii polylines
-1.0 40.0 A 1x1 degree rectangle centered on the
1.0 40.0 (0,39) point
1.0 38.0
-1.0 38.0
-1.0 40.0
 
0.0 90.0 A meridian extending from the North pole to the South pole
0.0 -90.0
リーダー
このセクションでは、このポリライン・ファイルの読み込みに使用可能なリーダーについて説明します。
この例のソース・コード一式は、以下のファイルにあります。
<installdir>/samples/maps/userman/src/simplePolylineReader.cpp
メモ: ここには、説明の必要なコード部分のみを示します。
以下のように、SimplePolylineReader は、IlvMapFeatureIterator 抽象クラスを実装します。
#ifdef IL_STD
#include <fstream>
using namespace std;
#else
#include <fstream.h>
#endif
 
#include <ilviews/maps/mapfeature.h>
#include <ilviews/maps/format/mapinput.h>
#include <ilviews/maps/rendering/curverdr.h>
 
class ILVMAPSEXPORTED SimplePolylineReader
:public IlvMapFeatureIterator
{
public:
SimplePolylineReader(IlvDisplay* display,
const char* filename);
virtual ~SimplePolylineReader();
virtual IlvMapsError getInitStatus() const;
 
virtual const IlvMapFeature* getNextFeature(IlvMapsError& status);
 
virtual IlvBoolean getLowerRightCorner(IlvCoordinate& coordinate) const;
 
virtual IlvBoolean getUpperLeftCorner(IlvCoordinate&) const;
 
IlvFeatureRenderer* getDefaultFeatureRenderer(IlvDisplay *);
 
const IlvProjection* getProjection() const;
 
IlvBoolean emptyLine(const char* line);
 
IlvBoolean readHeader(const char* line);
 
int parseLine(const char* line,
IlvDouble* lng,
IlvDouble* lat,
char* comment);
IlvFeatureAttributeProperty* attributes(IlString& buffer,
IlvMapsError& status);
IlvMapFeatureIteratorDeclareClassInfo();
private:
static IlvMapsError _formatError;
ifstream _stream;
IlvMapLineString* _geometry;
IlvMapFeature* _feature;
IlvProjection* _projection;
 
IlvDisplay* _display;
IlvMapsError _status;
static IlvMapsError FormatError();
static void Init();
const IlvMapFeature* readPolyline(IlvMapsError& status);
};
 
IlvClassInfo の登録
(makeFeatureIterator メソッドが返すような) IlvMapFeatureIterator のクラスを決定するためには、IlvClassInfo 登録が必要です。新しいリーダー・クラスを登録するには、次のような定義済みマクロを使用します。
IlvMapFeatureIteratorDefineClassInfo(className,superClassName);
ここで、className は新しいリーダー・クラスの名前 (現在の例では SimplePolygonReader) で、superClassName はスーパークラスの名前 (現在の例では IlvMapFeatureIterator) です。
IlvMapFeatureIterator クラスは、次の方法で確認できます。
IlvMapFeatureIterator* reader;
......
IlvClassInfo* readerClass = reader->getClassInfo();
if (readerClass->isSubtypeOf(SimplePolygonReader::ClassInfo())) {
...
}
地理参照メソッド
ポリライン・ファイルの緯度と経度が度単位で表されていることから、地理投影図法であることがわかります。getProjection メソッドがIlvGeographicProjection を返すからです。getProjection メソッドは、読み込むファイルの投影図法が不明な場合に、null を返す場合があります。
SimplePolylineReader::SimplePolylineReader(IlvDisplay* display,
const char* filename)
:_display(display),
_status(IlvMaps::NoError()),
_stream(filename),
_geometry(0),
_feature(0),
_projection(new IlvGeographicProjection())
{
char line[1024];
_stream.getline(line, 1024);
if(readHeader(line) == IlvFalse)
_status = _formatError;
}
const IlvProjection*
SimplePolylineReader::getProjection() const {
return _projection;
}
 
バウンディング・ボックス・メソッド
データ形式のために、すべてのデータが読み込まれるまでポリラインのバウンディング・ボックスを取得できません。ここで、メソッド getUpperLeftCornergetLowerRightCorner は、IlvFalse を返し、これらのポイントが不明であることを示します。また、すべてのデータを読み込んで配列に置き、バウンディング・ボックスを計算する方法もあります。
IlvBoolean
SimplePolylineReader::getLowerRightCorner(IlvCoordinate& c) const {
return IlvFalse;
}
 
IlvBoolean
SimplePolylineReader::getUpperLeftCorner(IlvCoordinate& c) const {
return IlvFalse;
}
 
レンダリング・メソッド
getDefaultFeatureRenderer メソッドは、すべての地図機能がこの機能イテレーターで読み込まれるグラフィック・オブジェクトに変換可能なレンダラーを返す必要があります。IlvDefaultCurveRenderer は、タイプ IlvMapLineString のジオメトリーがある地図機能を処理できます。
IlvFeatureRenderer*
SimplePolylineReader::getDefaultFeatureRenderer(IlvDisplay *display) {
return new IlvDefaultCurveRenderer(display);
}
 
返された地図機能のジオメトリーが定義されておらず、代わりに派生クラスのインスタンスである場合、または地図機能のアトリビュートが色や線の幅などのレンダリング処理に使用する描画パラメーターを格納する場合、これらのアトリビュートや派生ジオメトリーを処理できるレンダリング・スタイルのレンダラーを提供する必要があります。色付き線のレンダラーを作成する を参照してください。
getNextFeature メソッド
IlvMapFeatureIterator::getNextFeature メソッドは、地図機能のジオメトリーを読み込み、ジオメトリーの処理に必要なすべての情報を保持する IlvMapFeature オブジェクトを作成します。次のコード例で読み込むジオメトリーは、ポリライン・ジオメトリーを定義するクラスの IlvMapLineString です。
const IlvMapFeature*
SimplePolylineReader::getNextFeature(IlvMapsError& status) {
return readPolyline(status);
}
 
ポリラインのポイントは、プライベート・メソッド readPolyline で読み込まれます。このメソッドはファイルの各行を読み込み、ポイントと関連するコメントの座標がある場合にそれを抽出します。
詳細は、次のようになります。
1. タイプ IlvMapLineString のジオメトリーを作成またはリセットし、地図機能に関連付けます。パフォーマンス向上のため、リーダーが常に IlvMapFeature の同じインスタンスを返すことに注意してください。ジオメトリーの割り当ても、それらポイントが最初に読み込まれる時点の 1 回だけで、getNextFeaure を呼び出すたびに空になります。getNextFeature メソッドが返した地図機能は揮発性なので、メソッドを再び呼び出す前にジオメトリーとアトリビュートを使用する必要があります。IlvMapFeatureIterator インターフェースを実装する、Rogue Wave Views Maps ライブラリーのすべてのリーダーはこのように動作します。
const IlvMapFeature*
SimplePolylineReader::readPolyline(IlvMapsError& status) {
 
if(_stream.eof())
return 0;
if(!_geometry)
_geometry = new IlvMapLineString();
else
_geometry->removeAll();
if(!_feature) {
_feature = new IlvMapFeature();
_feature->setGeometry(_geometry);
const IlvProjection* proj = getProjection();
if(proj)
_feature->setProjection(proj->copy());
}
 
2. 次に線が読み込まれます。ファイルの末尾 (EOF)、または空白行に達すると、読み込んだ最終機能を返します。
 
char line[1024];
int first = 1;
IlString buffer;
IlvCoordinate c;
 
while (1) {
_stream.getline(line, 1024);
 
if(_stream.eof() || emptyLine(line)) {
status = IlvMaps::NoError();
IlvFeatureAttributeProperty* prop =
attributes(buffer, status);
if(status != IlvMaps::NoError())
IlvWarning(IlvMaps::GetErrorMessage(status, _display));
_feature->setAttributes(prop);
buffer = 0;
return _feature;
}
 
3. 次に示すコードでは、parseLine メソッドによって、経度ポイントと緯度ポイントが読み込まれます。コメントがあると、それをコメント・バッファーに追加します。このバッファーは、後述する attributes メソッドによって処理されます。
 
double x, y;
char comment[1024];
int i = parseLine(line, &x, &y, comment);
 
if(i < 2) {
status = _formatError;
return 0;
}
 
c.x(x);
c.y(y);
 
if(i == 3)
buffer += comment;
 
4. ファイルから読み込まれた各ポイントを、行文字列のジオメトリーに追加します。
 
if(first) {
first = 0;
_geometry->setStartPoint(c);
} else {
_geometry->lineTo(c);
}
}
}
 
5. 地図機能に関連付けるフォーム・アトリビュートへコメントを抽出します。これは、attributes メソッドです。
IlvFeatureAttributeProperty*
SimplePolylineReader::attributes(IlString& buffer, IlvMapsError& status)
{
if(buffer.getLength() == 0)
return 0;
 
IlvUInt count = 1;
const char* name = "Comment";
 
const IlvMapClassInfo* attClass = IlvStringAttribute::ClassInfo();
const IlvBoolean nullable = IlvTrue;
 
IlvFeatureAttributeInfo* info =
new IlvFeatureAttributeInfo( count,
&name,
&attClass,
&nullable);
 
const char* val = buffer.getValue();
IlvStringAttribute* att =
new IlvStringAttribute();
att->setValue(val);
 
IlvFeatureAttributeProperty* prop =
new IlvFeatureAttributeProperty(info,
(IlvFeatureAttribute**)&att,
status);
 
return prop;
}
 

Version 6.0
Copyright © 2015, Rogue Wave Software, Inc. All Rights Reserved.