GDALではPCIDSKの面ベクトルフォーマットはサポートされていません


最近GDALを使ってPCIDSK形式のベクトルデータを作成していますが、点と線のベクトルデータを作成しても問題なく、面状を作成しているのは属性テーブルだけで図形がありません.GDAL公式サイトでの説明もサポートされています.住所は:http://www.gdal.org/frmt_pcidsk.html.
仕方なくGDALのソースコードをめくってみると、SetFeatureの場合、wkbPointとwkbLineStringタイプしか書かれておらず、その他のプラス文Debugコードは以下の通りです.
            CPLDebug( "PCIDSK", "Unsupported geometry type in SetFeature(): %s",
                      poGeometry->getGeometryName() );
これはあまりにも......仕方なく自分で研究して補うしかない.
GDAL読み取りを見ると、面状のベクトルに対してPCIDSKはベクトルセグメント内の属性テーブルにRingStartというフィールドを多く保存しており、タイプはIntListで、ポリゴン内の各リングの開始点番号を格納するために使用されている.PCIDSKのベクトルデータについては、すべての点が大きな配列に格納されており、多角形については、複数のリングからなる可能性があり、これらのリングの中のすべての点が1つの配列に存在し、各リングの頂点座標をどのように区別するかは、RingStartの中の値によって分割する必要がある.記憶の原理がわかったら、この原理に従って多角形を書いた部分を補うといいでしょう.修正されたコードは次のとおりです.
		else if( wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon )
		{
			OGRPolygon *poPoly = (OGRPolygon *) poGeometry;
			int nRingSize = poPoly->getNumInteriorRings();
			
			std::vector<PCIDSK::int32> anRingStart;
			anRingStart.resize(nRingSize+1);
			
			OGRLinearRing *poRing = NULL;
			poRing = poPoly->getExteriorRing();
			anRingStart[0] = poRing->getNumPoints();
			
			aoVertices.resize(poRing->getNumPoints());
			for(int i = 0; i < aoVertices.size(); i++ )
			{
				aoVertices[i].x = poRing->getX(i);
				aoVertices[i].y = poRing->getY(i);
				aoVertices[i].z = poRing->getZ(i);
			}

			for (int iRing=0; iRing < nRingSize; iRing++)
			{
				int nCurrentStart = aoVertices.size();
				poRing = poPoly->getInteriorRing(iRing);
				anRingStart[iRing+1] = nCurrentStart + poRing->getNumPoints();
				aoVertices.resize(nCurrentStart + poRing->getNumPoints());

				for(int i = nCurrentStart; i < aoVertices.size(); i++ )
				{
					aoVertices[i].x = poRing->getX(i-nCurrentStart);
					aoVertices[i].y = poRing->getY(i-nCurrentStart);
					aoVertices[i].z = poRing->getZ(i-nCurrentStart);
				}
			}
			
			if(iRingStartField == -1)
			{
				iRingStartField = poVecSeg->GetFieldCount();
				//poVecSeg->AddField( "RingStart", PCIDSK::FieldTypeCountedInt, "", "" );
	  			OGRFieldDefn oField( "RingStart", OFTIntegerList );
	  			//oField.SetWidth(100);
	  			CreateField( &oField );
			}

			std::vector<PCIDSK::ShapeField> aoShapeFields;
			poVecSeg->GetFields(id, aoShapeFields);

			aoShapeFields[iRingStartField].SetValue(anRingStart);
			poVecSeg->SetFields( id, aoShapeFields );
		}
修正が終わったらGDALを再コンパイルすればいいです.
=============================================
上のコードで1つの面状のpixファイルを生成することができ、GDALで開くのも問題ありませんが、FocusやMosaicToolで開くとこの2つのプログラムがクラッシュし、属性値表示に一定の問題があります.今日はさらに下の部分のコードをよく見てみると、内輪のない多角形、つまり一つのFeatureの中に多角形が一つしかない場合、RingStartという属性値を書く必要はなく、油を含む内輪の場合、つまり多角形に内輪がある場合にのみ必要となるので、上のコードを次のコードに変更します.
		else if( wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon )
		{
			OGRPolygon *poPoly = (OGRPolygon *) poGeometry;
			OGRLinearRing *poRing = NULL;
			poRing = poPoly->getExteriorRing();
			
			aoVertices.resize(poRing->getNumPoints());
			for(int i = 0; i < aoVertices.size(); i++ )
			{
				aoVertices[i].x = poRing->getX(i);
				aoVertices[i].y = poRing->getY(i);
				aoVertices[i].z = poRing->getZ(i);
			}

			int nRingSize = poPoly->getNumInteriorRings();
			if(nRingSize > 0 )
			{
				std::vector<PCIDSK::int32> anRingStart;
				anRingStart.resize(nRingSize+1);
				anRingStart[0] = poRing->getNumPoints();

				for (int iRing=0; iRing < nRingSize; iRing++)
				{
					int nCurrentStart = aoVertices.size();
					poRing = poPoly->getInteriorRing(iRing);
					anRingStart[iRing+1] = nCurrentStart + poRing->getNumPoints();
					aoVertices.resize(nCurrentStart + poRing->getNumPoints());

					for(int i = nCurrentStart; i < aoVertices.size(); i++ )
					{
						aoVertices[i].x = poRing->getX(i-nCurrentStart);
						aoVertices[i].y = poRing->getY(i-nCurrentStart);
						aoVertices[i].z = poRing->getZ(i-nCurrentStart);
					}
				}
				
				if(iRingStartField == -1)
				{
					iRingStartField = poVecSeg->GetFieldCount();
					OGRFieldDefn oField( "RingStart", OFTIntegerList );
					CreateField( &oField );
				}

				std::vector<PCIDSK::ShapeField> aoShapeFields;
				poVecSeg->GetFields(id, aoShapeFields);
				aoShapeFields[iRingStartField].SetValue(anRingStart);
				poVecSeg->SetFields( id, aoShapeFields );
			}
		}
これで生成されたFoucsとMosaicToolを使用すると正常に開くことができ、プログラムもクラッシュすることはありませんが、属性値の表示にはまだ小さな問題がありますが、使用には影響しません.