Web ADF基盤における地理空間データ型の変換処理

Webアプリケーション開発フレームワーク(Web ADF)は、複数のデータソースと通信階層を跨いで動作するため、クライアント画面の座標情報、サーバー側のジオメトリ形式、COMオブジェクト間でのデータ受け渡しに頻繁な型変換が要求されます。各階層やデータソースは独自の実装を持ち独立して動作するため、Web ADFの開発者はそれらを統合する役割を担い、適切なコンバーターを呼び出す処理を実装する必要があります。

コンバータークラスの構成

ネームスペースごとに役割が分化した静的メソッド群が提供されており、変換対象となるAPIに合わせて選択します。

ネームスペース主な用途
ESRI.ArcGIS.ADF.ArcGISServer.ConverterArcGIS Server SOAP/Valueオブジェクト間の相互変換、シリアライズ処理
ESRI.ArcGIS.ADF.Converter認証情報の暗号化、イメージビットマップ生成
ESRI.ArcGIS.ADF.Web.Converter.NET DataTable/DataSet から Web ADF グラフィクスデータセットへの変換
ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.ConverterArcGIS Server COM(Value) と Web ADF ジオメトリ・レイヤー間の双方向変換
ESRI.ArcGIS.ADF.Web.DataSources.IMS.ConverterArcIMS 固有の座標単位およびジオメトリ型の変換
ESRI.ArcGIS.ADF.Web.UI.WebControls.ConverterUI コントロール内部処理用(上記と同じ機能を提供)

※一部カスタムデータソースAPIは独自の変換ロジックを保持することがあります。

座標系変換と回転対応

ブラウザ表示領域(ピクセル単位)と地図座標系では単位が異なるため、Web ADF は内部ジオメトリライブラリを中間層として機能させます。回転マップに対応させる場合、TransformationParams クラスを使用して座標マッピングを行います。Map.GetTransformationParams(TransformationDirection) で取得したパラメータを引数に渡すことで、ToMapPoint や座標伸張処理が正確に座標系を反映します。なお、ArcGIS Server のカーブベースジオメトリは直接サポートされないため、必要に応じて Densify() メソッドで頂点補間を適用する必要があります。

ジオメトリ型変換パターン

以下に、クリック座標から得られたスクリーン値を起点に、各ターゲット形式への変換ロジックを示します。変数名と構造を整理し、冗長な反復処理を削除しています。

ポイント (Point)

// スクリーン座標 → Web ADF
var ctx = mainMap.GetTransformationParams(TransformationDirection.ToMap);
ESRI.ArcGIS.ADF.Web.Geometry.Point adfPt = ESRI.ArcGIS.ADF.Web.Geometry.Point.ToMapPoint(screenX, screenY, ctx);

// Web ADF → ArcGIS Server SOAP(Value)
ESRI.ArcGIS.ADF.ArcGISServer.PointN soapPt = 
    ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.FromAdfPoint(adfPt);

// Web ADF → ArcObjects(COM)
var localFunc = (ArcGISServer.MapFunctionality)mainMap.GetFunctionality(0);
var localRes = (ArcGISServer.MapResourceLocal)localFunc.Resource;
ESRI.ArcGIS.Geometry.IPoint comPt = 
    ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToIGeometry(adfPt, localRes.ServerContextInfo.ServerContext) as ESRI.ArcGIS.Geometry.IPoint;

ポリライン (Polyline)

// スクリーン多点入力 → Web ADF
var inputPts = new[] { new Point(10, 10), new Point(50, 60), new Point(90, 20) };
var pathCol = new ESRI.ArcGIS.ADF.Web.Geometry.PathCollection();
foreach (var coord in inputPts)
{
    var mapped = ESRI.ArcGIS.ADF.Web.Geometry.Point.ToMapPoint(coord, mainMap.Extent, 
        mainMap.GetTransformationParams(TransformationDirection.ToMap));
    pathCol.Add(new ESRI.ArcGIS.ADF.Web.Geometry.Path(new[] { mapped }));
}
ESRI.ArcGIS.ADF.Web.Geometry.Polyline adfLine = new ESRI.ArcGIS.ADF.Web.Geometry.Polyline(pathCol);

// Web ADF → SOAP / COM
ESRI.ArcGIS.ADF.ArcGISServer.PolylineN soapLine = 
    ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.FromAdfPolyline(adfLine);

ESRI.ArcGIS.Geometry.IPolyline comLine = 
    ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToIGeometry(adfLine, localRes.ServerContextInfo.ServerContext) as ESRI.ArcGIS.Geometry.IPolyline;

ポリゴン (Polygon)

// スクリーン閉曲線 → Web ADF
var ringCoords = new[] { new Point(20,20), new Point(80,20), new Point(80,80), new Point(20,80) };
var pts = new ESRI.ArcGIS.ADF.Web.Geometry.PointCollection();
foreach (var p in ringCoords)
{
    pts.Add(ESRI.ArcGIS.ADF.Web.Geometry.Point.ToMapPoint(p, mainMap.Extent, 
        mainMap.GetTransformationParams(TransformationDirection.ToMap)));
}
ESRI.ArcGIS.ADF.Web.Geometry.Polygon adfPoly = new ESRI.ArcGIS.ADF.Web.Geometry.Polygon(new[] { new Ring(pts) });

// Web ADF → COM
ESRI.ArcGIS.Geometry.IPolygon comPoly = 
    ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToIGeometry(adfPoly, localRes.ServerContextInfo.ServerContext) as ESRI.ArcGIS.Geometry.IPolygon;

※COM側で Buffer() 等により生成されたジオメトリをWeb ADF型へ逆変換する場合、頂点数が不足している可能性が高いため、事前に IPolygon.Densify() を呼び出して補間しておく必要があります。

COMとSOAP Valueオブジェクトのブリッジ

ArcGIS Server ローカル接続ではサーバーコンテキスト経由でCOM APIへアクセス可能ですが、Web ADFの基本インターフェースはステートレスなSOAP(Value)プロキシを標準で使用します。これら2つの表現形式間で同期するには以下のメソッドを利用します。

// COM → SOAP Value
var serverCtx = ...; // IServerContext インスタンス
ESRI.ArcGIS.ADF.ArcGISServer.PolylineN soapObj = 
    ESRI.ArcGIS.ADF.ArcGISServer.Converter.ComObjectToValueObject(comObj, serverCtx, typeof(ESRI.ArcGIS.ADF.ArcGISServer.PolylineN)) as ESRI.ArcGIS.ADF.ArcGISServer.PolylineN;

// SOAP Value → COM
ESRI.ArcGIS.Geometry.IPolyline backToCom = 
    ESRI.ArcGIS.ADF.ArcGISServer.Converter.ValueObjectToComObject(soapObj, serverCtx) as ESRI.ArcGIS.Geometry.IPolyline;

SOAP API は ArcObjects の一部を公開しているため、全てのCOM型に対応するValue型が存在するわけではありません。主に IPoint, ILine, IPolyline, IPolygon, IMapDescription, IGraphicElements, IField, IRecordSet 等のペアが標準的に定義されています。

表データとグラフィックスレイヤーへの変換

クエリ結果や属性テーブルを扱う際、レコードセット形式のデータはADO.NET準拠の構造体へ変換されます。Web ADFの IQueryFunctionality から返されるDataTableにはジオメトリ情報が含まれますが、そのままでは地図上に図形として描画できません。これを解決するために Converter.ToGraphicsLayer が提供されています。

// クエリ実行
var resultTable = queryFunc.Query(null, layerIds[0], spatialFilter);

// テーブルをグラフィックスレイヤーに変換(指定色で表示)
ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer gfxLayer = 
    ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(resultTable, Color.Yellow, Color.Blue);
    
// マップリソースへ追加
var selRes = gisFuncColl.FirstOrDefault(f => f.Resource.Name == "Selection")?.Resource;
if (selRes is ArcGIS.ADF.Web.DataSources.Graphics.MapResource mgr)
{
    mgr.Graphics.Tables.Clear();
    mgr.Graphics.Tables.Add(gfxLayer);
}

変換先のレイヤー種別は自動判定されます。DataTable内のジオメトリが全て同一形状の場合 FeatureGraphicsLayer が、異種混在の場合は ElementGraphicsLayer が返却され、それぞれマップリソースのコレクションへ直接格納可能です。また、ジオメトリ値をカラムに含む RecordSet を Converter.ToFeatureGraphicsLayer に渡すことで、地図制御ウィジェットへの展開も簡素化できます。

タグ: ArcGIS WebADF csharp ジオメトリ変換 ArcObjects

6月9日 21:53 投稿