「NTS」を利用して、ポリゴンの中心点を抽出し、shpに保存したところポイントの図形がPOINTではなくPOINTZ(3次元)に設定されていました。
1.原因分析1
ポリゴンから中心点の抽出は以下のプロパティを使っています。PointOnSurfaceは、図形上の
中心点を取得します。それでも取得できない場合は、Centroidを使用します。Centroidはポリゴンの形状により図形上にない場合があります。
1 2 3 4 5 |
var center = feature.Geometry.PointOnSurface; if(center == null) { center = feature.Geometry.Centroid; } |
2.原因分析2
これらのプロパティの処理をを追っていくと、図形生成クラス(GeometryFactory)でポイントを生成するメソッドCreatePoint()を読んでします。
1 2 3 4 |
public IPoint CreatePoint(Coordinate coordinate) { return CreatePoint(coordinate != null ? CoordinateSequenceFactory.Create(new[] { coordinate }) : null); } |
3.原因分析3
さらに追っていくと、CoordinateArraySequenceクラスのコンストラクタで、dimensionが4に設定されていました。
dimensionは次元を意味し、デフォルトの場合は何故か4が設定されています。これが原因でした。
1 2 3 4 5 6 7 8 9 10 11 |
/// dimensionなしのコンストラクタ public CoordinateArraySequence(Coordinate[] coordinates): this(coordinates, 4) { } /// dimension付きのコンストラクタ public CoordinateArraySequence(int size, int dimension) { Coordinates = new Coordinate[size]; _dimension = dimension; for (var i = 0; i < size; i++) Coordinates[i] = new Coordinate(); } |
4.対策1
図形生成クラス(GeometryFactory)では、CreatePointを使用する場合は、Coordinateではなく、CoordinateArraySequenceを引数に使用します。CoordinateArraySequenceでは、dimensionの指定ができるので2次元を設定します。
1 2 3 4 5 6 7 |
var point = feature.Geometry.Centroid; // 2次元を指定 var coordinates = new CoordinateArraySequence( new Coordinate[] { new Coordinate(point.X, point.Y) }, 2) center = GeometryFactory.Default.CreatePoint(coordinates)); |
5.対策2
もう一つの対策は、WKTを利用します。WKTの場合は、デフォルトの場合でも2次元に設定されます。
以下例
1 2 3 4 5 6 |
var wktReader = new WKTReader(); var feature = new Feature(); var wkt = new StringBuilder(); wkt.AppendFormat("POINT("); wkt.AppendFormat("{0} {1})",point.X,point.Y); feature.Geometry = wktReader.Read(wkt.ToString()); |
以下、対策後のデータ