bool CsvImportProcessorImpl::AddFeature(Row* pRow, FeatureClass* pFeatureClass, FeatureInsertCommand* cmd)
	{
		GField*	 pField  = NULL;
		GFields* pFields = pFeatureClass->GetFields();
		Feature* pFeature = pFeatureClass->NewFeature();
		GValue* pValue = NULL;
		const char* fname = NULL;
		augeFieldType ftype = augeFieldTypeNone;
		
		const char* str = NULL;
		
		g_uint fcount = pFields->Count();
		for(g_uint i=0; i<fcount; i++)
		{
			pField = pFields->GetField(i);
			fname = pField->GetName();
			ftype = pField->GetType();

			str = pRow->GetString(fname);
			if(str==NULL)
			{
				continue;
			}
			switch(ftype)
			{
			case augeFieldTypeShort:
				pValue = new GValue((short)atoi(str));
				break;
			case augeFieldTypeInt:
				pValue = new GValue((int)atoi(str));
				break;
			case augeFieldTypeLong:
				pValue = new GValue((long)atoi(str));
				break;
			case augeFieldTypeInt64:
				pValue = new GValue((int64)atoi(str));
				break;
			case augeFieldTypeFloat:
				pValue = new GValue((float)atof(str));
				break;
			case augeFieldTypeDouble:
				pValue = new GValue((double)atof(str));
				break;
			case augeFieldTypeString:
				pValue = new GValue(str);
				break;
			}
			pFeature->SetValue(fname, pValue);
		}
		
		RESULTCODE rc = cmd->Insert(pFeature);
		pFeature->Release();

		return (rc==AG_SUCCESS);
	}
	bool TransactionHandler::Insert(XNode* pxInsert, WebContext* pWebContext, FeatureWorkspace* pWorkspace)
	{	
		XNode* pxType = pxInsert->GetFirstChild();
		if(pxType==NULL)
		{
			return false;
		}

		GLogger* pLogger = augeGetLoggerInstance();
		GError*  pError  = augeGetErrorInstance();
		RESULTCODE rc = AG_FAILURE;

		const char* name = pxType->GetName();
		FeatureClass* pFeatureClass = NULL;
		pFeatureClass = pWorkspace->OpenFeatureClass(name);
		if(pFeatureClass==NULL)
		{
			char msg[AUGE_MSG_MAX];
			g_snprintf(msg, AUGE_MSG_MAX, "Fail to get FeatureClass [%s]", name);
			pLogger->Error(msg, __FILE__, __LINE__);
			pError->SetError(msg);
			return false;
		}

		Feature* pFeature = pFeatureClass->NewFeature();
		if(pFeature==NULL)
		{
			return false;
		}

		GField	*pField  = NULL;
		GFields	*pFields = pFeatureClass->GetFields();
		const char* fname = NULL;
		bool ok = true;

		GValue* pValue = NULL;
		XNode* pxNode = NULL;
		XNodeSet* pxNodeSet = pxType->GetChildren();
		pxNodeSet->Reset();
		while((pxNode=pxNodeSet->Next())!=NULL)
		{
			fname = pxNode->GetName();
			pField = pFields->GetField(fname);
			if(pField!=NULL)
			{
				pValue = CreateValue(pxNode, pField);
				if(pValue!=NULL)
				{
					pFeature->SetValue(fname, pValue);
				}
				else
				{
					char msg[AUGE_MSG_MAX];
					g_snprintf(msg, AUGE_MSG_MAX, "Field [%s]: Invalid Value", fname);
					pLogger->Error(msg, __FILE__, __LINE__);
					pError->SetError(msg);

					ok = false;
					break;
				}
			}
			else
			{
				char msg[AUGE_MSG_MAX];
				g_snprintf(msg, AUGE_MSG_MAX, "FeatureClss does not have Field [%s]", fname);
				pLogger->Error(msg, __FILE__, __LINE__);
				pError->SetError(msg);
				
				ok = false;
				break;
			}
		}
		pxNodeSet->Release();

		if(ok)
		{
			FeatureInsertCommand* cmd = pFeatureClass->CreateInsertCommand();
			rc = cmd->Insert(pFeature);
			AUGE_SAFE_RELEASE(cmd);	
		}		

		AUGE_SAFE_RELEASE(pFeature);		
		AUGE_SAFE_RELEASE(pFeatureClass);

		return !rc;
	}
	bool TransactionHandler::Insert(XNode* pxInsert, WebContext* pWebContext, Map* pMap)
	{	
		XNode* pxLayer = pxInsert->GetFirstChild();
		if(pxLayer==NULL)
		{
			return false;
		}
		const char* name = pxLayer->GetName();
		Layer *pLayer = pMap->GetLayer(name);
		if(pLayer==NULL)
		{
			return false;
		}

		augeLayerType ltype = pLayer->GetType();
		if(ltype != augeLayerFeature)
		{
			return false;
		}

		FeatureLayer* pFeatureLayer = NULL;
		pFeatureLayer = static_cast<FeatureLayer*>(pLayer);
		
		FeatureClass* pFeatureClass = NULL;
		pFeatureClass = pFeatureLayer->GetFeatureClass();
		if(pFeatureClass==NULL)
		{
			return false;
		}

		Feature* pFeature = pFeatureClass->NewFeature();
		if(pFeature==NULL)
		{
			return false;
		}

		GField	*pField  = NULL;
		GFields	*pFields = pFeatureClass->GetFields();
		const char* fname = NULL;

		GValue* pValue = NULL;
		XNode* pxNode = NULL;
		XNodeSet* pxNodeSet = pxLayer->GetChildren();
		pxNodeSet->Reset();
		while((pxNode=pxNodeSet->Next())!=NULL)
		{
			fname = pxNode->GetName();
			pField = pFields->GetField(fname);
			if(pField!=NULL)
			{
				pValue = CreateValue(pxNode, pField);
				if(pValue!=NULL)
				{
					pFeature->SetValue(fname, pValue);
				}
			}
		}
		pxNodeSet->Release();

		FeatureInsertCommand* cmd = pFeatureClass->CreateInsertCommand();
		RESULTCODE rc = cmd->Insert(pFeature);
		
		AUGE_SAFE_RELEASE(pFeature);
		AUGE_SAFE_RELEASE(cmd);

		return !rc;
	}
	void PolygonToLineProcessorImpl::ProcessMultiPolygon(Feature* pinFeature, FeatureClass* poutFeatureClass, FeatureInsertCommand* cmd)
	{
		Geometry* pGeometry = NULL;
		pGeometry = pinFeature->GetGeometry();
		if(pGeometry==NULL)
		{
			return;
		}

		const char* fname = NULL;
		GField*  pField = NULL;
		GFields* pFields = pinFeature->GetFeatureClass()->GetFields();
		g_uint count = pFields->Count();

		GValue* pValue = NULL;
		GValue* pGeoValue = NULL;		
		Feature* poutFeature = poutFeatureClass->NewFeature();

		augeFieldType type = augeFieldTypeNone;
		for(g_uint i=0; i<count; i++)
		{
			pField = pFields->GetField(i);
			type = pField->GetType();
			if(type==augeFieldTypeGeometry)
			{
				continue;
			}

			fname = pField->GetName();
			pValue = pinFeature->GetValue(i);			
			poutFeature->SetValue(fname, pValue);
		}

		Geometry* pGeoLine = NULL;
		GeometryFactory* pGeometryFactory = augeGetGeometryFactoryInstance();
		pField = pinFeature->GetFeatureClass()->GetFields()->GetGeometryField();
		if(pField!=NULL)
		{
			pValue = pinFeature->GetValue(pField->GetName());
			if(pValue!=NULL)
			{
				pGeometry = pValue->GetGeometry();
				if(pGeometry!=NULL)
				{
					g_uint numPoints = 0;
					g_uint numRings = 0;
					g_uint numPolygons = 0;
					g_uint ring_size = 0;
					g_uint line_size = 0;
					LinearRing* pLinearRing = NULL;
					WKBPolygon* pWKBPolygon = NULL;
					WKBMultiPolygon* pWKBMultiPolygon = (WKBMultiPolygon*)pGeometry->AsBinary();
					WKBLineString* pWKBLineString = NULL;
					g_byte* ptr = NULL;

					numPolygons = pWKBMultiPolygon->numPolygons;
					pWKBPolygon = (WKBPolygon*)(&(pWKBMultiPolygon->polygons[0]));
					for(g_uint i=0; i<numPolygons; i++)
					{
						numRings = pWKBPolygon->numRings;
						pLinearRing = (LinearRing*)(&(pWKBPolygon->rings[0]));
						for(g_uint j=0; j<numRings; j++)
						{
							numPoints = pLinearRing->numPoints;
							ring_size = sizeof(auge::Point) * numPoints + sizeof(g_int32);
							line_size = ring_size + sizeof(g_int32) + sizeof(g_byte);

							pWKBLineString = (WKBLineString*)malloc(line_size);
							memset(pWKBLineString, 0, line_size);

							pWKBLineString->byteOrder = coDefaultByteOrder;
							pWKBLineString->wkbType = wkbLineString;
							pWKBLineString->numPoints = numPoints;
							memcpy(&(pWKBLineString->points[0]), &(pLinearRing->points[0]), sizeof(auge::Point) * numPoints);

							pGeoLine = pGeometryFactory->CreateGeometryFromWKB((g_byte*)(pWKBLineString), true);
							pGeoValue = new GValue(pGeoLine);
							poutFeature->SetValue(pField->GetName(), pGeoValue);

							cmd->Insert(poutFeature);

							free(pWKBLineString);

							ptr = (g_byte*)pLinearRing;
							pLinearRing = (LinearRing*)(ptr + ring_size);
						}
						pWKBPolygon = (WKBPolygon*)pLinearRing;
					}
				}
			}
		}
		poutFeature->Release();
	}