mapgis6.7二次开发vc6_demo 之四(VCT导出之 version=1,topo=0)

mapgis6.7二次开发vc6_demo 之四(VCT导出之 version=1,topo=0)

本文所述内容为国土行业的VCT版本为1,拓扑=0的结构

即为2002年国家标准

本文主要包括有(

vct文件头段输出功能;

vct要素类段输出功能;

vct字段结构输出功能;

vct线要素几何图形输出功能;

vct属性结构输出功能;)

其中vct点要素几何图形输出功能;

        vct面要素几何图形输出功能;

        vct注记几何图形输出功能;

将在后续的文章中描述;

//Vct_Export.cpp文件内容如下所示:

//
//
//VCT 导出功能 version=1, topo=0 
//
//
#include "stdafx.h"
#include "resource.h"
#include <math.h>
#include "win_area.h"
#include "win_oper.h"
#include "map_out.h"
#include "demo.h"
//
extern char* AppTitle;                    //应用程序名称
extern AREA_HINST    AHInst;
extern HWND         MainWnd;              //主窗口句柄
extern HWND         GrpWnd;               //图形窗口句柄

//long  _GetDiskSpace(unsigned char dsk)
//参数:入口   dsk 磁盘号, 1=A,2=B...
//     出口   无
//返回值 返回磁盘剩余空间的字节数
char* GetDiskSpace_lc(unsigned char dsk)
{
    long sy=_GetDiskSpace(dsk); //
	long M=sy/1024;  
	char* atitle;
	int mLen=sizeof(M);
	atitle=new char[mLen];
	ltoa(M,atitle,mLen);
	return atitle;
}
char* l2cp(long n)
{
    int nLen=sizeof(n);
	char* atitle=new char[nLen];
	ltoa(n,atitle,nLen);
	return atitle;
}
char* i2cp(int n)
{
	int nLen=sizeof(n);
	char* atitle=new char[nLen];
	itoa(n,atitle,nLen);
	return atitle;    
}
char* d2cp(double value)
{
	/*
   char *tt;    
   int dec, sign; 
   int ndig = 10; 
   tt = ecvt(value, ndig, &dec, &sign); 
   //tt = fcvt(value, ndig, &dec, &sign);
   return tt;*/
	char* s=new char[sizeof(value)];
	sprintf(s,"%8.6f",value); 
    char* ret_s=new char[strlen(s)];
	strcpy(ret_s,s);
	return ret_s;
}
char* short2cp(short value)
{
    char* s=new char[sizeof(value)];
	sprintf(s,"%d",value); 
    char* ret_s=new char[strlen(s)];
	strcpy(ret_s,s);
	return ret_s;
}
char* a2u(const char* A,const char* B)
{
    return strcat_lc(A,B);
}
char* a3u(const char* A,const char* B,const char* C)
{
	char* t=strcat_lc(A,B);
	t=strcat_lc(t,C);
    return t;
}
char* a4u(const char* A,const char* B,const char* C,const char* D)
{
	char* t=strcat_lc(A,B);
	t=strcat_lc(t,C);
	t=strcat_lc(t,D);
    return t;
}
char* a5u(const char* A,const char* B,const char* C,const char* D,const char* E)
{
	char* t=strcat_lc(A,B);
	t=strcat_lc(t,C);
	t=strcat_lc(t,D);
	t=strcat_lc(t,E);
    return t;
}
char* a6u(const char* A,const char* B,const char* C,const char* D,const char* E,const char* F)
{
	char* t=strcat_lc(A,B);
	t=strcat_lc(t,C);
	t=strcat_lc(t,D);
	t=strcat_lc(t,E);
	t=strcat_lc(t,F);
    return t;
}
char* a7u(const char* a1,const char* a2,const char* a3,const char* a4,const char* a5,const char* a6,const char* a7)
{
	char* t=strcat_lc(a1,a2);
	t=strcat_lc(t,a3);
	t=strcat_lc(t,a4);
	t=strcat_lc(t,a5);
	t=strcat_lc(t,a6);
	t=strcat_lc(t,a7);
    return t;
}
char* substr_lc(const char* cs,char* fd)
{
     return strstr(cs,fd);
}
char* getdir_lc(char* s,const char* d)
{	
	char* s_s=new char[strlen(s)];
	strcpy(s_s,s);
	char* s_rev=strrev(s_s);
	char* t_rev=strstr(s_rev,d);
	char* t=strrev(t_rev);
	return t;
}
char* getfilename_lc(char* s,const char* d)
{	
    char* t_dir=getdir_lc(s,d);
	//
	char* s_s=new char[strlen(s)];
	strcpy(s_s,s);
	int dir_len=strlen(t_dir);
	int fn_len=strlen(s_s)-dir_len;
    char* fn_ext=new char[fn_len];
	memset(fn_ext,0,fn_len);
	//
	for(int i=0;i<fn_len;i++)
	{
		fn_ext[i]=s_s[dir_len+i];
	}
	char* ret_s=new char[strlen(fn_ext)];
	strcpy(ret_s,fn_ext);
	return ret_s;
}
void ShowMsg(char* msg)
{    
	::MessageBox(NULL,msg,"提示",0);
	//_MapGisAbout(msg);
}
void TestGetDiskSpace()
{
    char* atitle=GetDiskSpace_lc(4);
	//char* atitle=AppTitle;
	ShowMsg(atitle);
	//MessageBox(hWnd,(LPCSTR)m,(LPCSTR)m,NULL);     
    //_DispAbout();
}
void D2A_test()
{
	//查看属性
	_ViewAtt(MainWnd,AHInst,0);
	//查看mapgis图层字段结构api
	_ViewStruct(MainWnd,AHInst);

	char* s;
	double value;
	int dec,sign;
	int ndig=2;  //字符串长度
	value=35951234.876533324234;
    s=ecvt(value,ndig,&dec,&sign);	
	ShowMsg(a5u(s,",dec=",i2cp(dec),",sign=",i2cp(sign)));
	sprintf(s,"%8.6f",value);  //OK
	ShowMsg(s);

	//
	value=-123.45;
	ndig=15;
	s=ecvt(value,ndig,&dec,&sign);
	ShowMsg(a5u(s,",dec=",i2cp(dec),",sign=",i2cp(sign)));
	//
	value=0.6789e5;
	ndig=5;
	s=ecvt(value,ndig,&dec,&sign);
	ShowMsg(a5u(s,",dec=",i2cp(dec),",sign=",i2cp(sign)));
	return;
}

//输出VCT文件头 OK
bool OutVctHeadBeginEnd()
{
    bool rbc = false;
    //ShowMsg(this, "正在输出Vct文件头信息");
    //输出VCT头标志
    double L0 = 105;
    double tmp_a = 6378140;   //默认为西安80椭球体参数
    double tmp_b = 6356755.288157528574350308626453;  //6356755;
    char* Spheroid = "Krassovesky Spheroid";            
    char* tmpDate ="20120412";// System.DateTime.Now.ToString("yyyyMMdd");
	char* Parameters=a3u(d2cp(tmp_a), ",",d2cp(tmp_b));
	//
    f_WriteLine("HeadBegin");
    f_WriteLine("DataMark: CNSDTF-VCT");  //(国家标准 地球空间数据交换格式2002年)
    f_WriteLine("Version: 1.0");
    f_WriteLine("Unit: M");
    f_WriteLine("Dim: 2");
    f_WriteLine("Topo: 0");
    f_WriteLine("Coordinate: M");
    f_WriteLine("Projection: Gauss-Kruger Projection");
    f_WriteLine(a2u("Spheroid: ",Spheroid));      //Spheroid: Krassovesky Spheroid	
    f_WriteLine(a2u("Parameters: ",Parameters));   //Parameters: 6378140,6356755
    f_WriteLine(a2u("Meridinan: ", d2cp(L0)));    //Meridinan: 105
    f_WriteLine("MinX: 0.000000");
    f_WriteLine("MinY: 0.000000");
    f_WriteLine("MaxX: 99999999.999999");
    f_WriteLine("MaxY: 9999999.999999");
    f_WriteLine("ScaleM:10000");
    f_WriteLine(a2u("Date:" , tmpDate));
    f_WriteLine("Separator: ,");
    f_WriteLine("HeadEnd");
    f_WriteLine("");
    //ShowMsg(this, "完成输出Vct文件头信息");
    rbc = true;
    return rbc;
}

//输出vct要素代码 OK
bool OutVctFeatureCodeBeginEnd(short* ptALst)
{
    bool rbc = false;    
    char* GeoVctType = "";
    char* FeatClassName = "";
    char* FeatureCode = "";
    char* FeatureName = "";

	short ai,LayerType;	
	char* Lfilename;

    //this.ShowMsg(this, "正在输出要素代码信息");
    //#region 输出要素代码
    int indexLayer = 0; 
    f_WriteLine("FeatureCodeBegin");
    for(int k=1;k<=ptALst[0];k++)
    {   //获取一个工作区
		ai=ptALst[k]; 
		//获取工作区文件名
		Lfilename=_GetAreaFileName(ai);
		//获取图层类型
		LayerType=_GetAreaType(ptALst[k]);
		GeoVctType="UnKown";
		switch(LayerType)
		{
			case REG:
				GeoVctType="Polygon";
				break;
			case LIN:
				GeoVctType="Line";
				break;
			case PNT:
                GeoVctType="Point";
				break;
			default:
				break;
		}
        
        FeatClassName =Lfilename;

        FeatureCode =a3u(GeoVctType,"_",i2cp(k));
        FeatureName =FeatureCode;

        //this.ShowMsg(this, "正在输出要素代码" + zhfeatclass.GetAliasName + "[" + FeatClassName + "]");
        //this.SetValue(++indexLayer);

        f_WriteLine(a7u(FeatureCode , "," , FeatureName , "," , GeoVctType , ",0," , FeatClassName));  //Polygon/Line/Point
        //f_WriteLine("B11,地类图斑,Polygon,0,DLTB");
        //f_WriteLine("B12,线状地物,Line,0,XZDW");
        //f_WriteLine("C10,土地用途分区,Polygon,0,YTFQ");
        //f_WriteLine("C20,基本农田保护,Polygon,0,JBNT");
        //f_WriteLine("C30,土地整理,Polygon,0,TDZL");
        //f_WriteLine("C40,土地复垦,Polygon,0,TDFK");
        //f_WriteLine("C50,土地开发,Polygon,0,TDKF");
        //f_WriteLine("C71,面状建设项目,Polygon,0,MZXM");
        //f_WriteLine("C72,线状建设项目,Line,0,XZXM");
        //f_WriteLine("E11,面状用地,Polygon,0,MZYD");
    }
    f_WriteLine("FeatureCodeEnd");
    f_WriteLine("");
    //this.ShowMsg(this, "完成输出要素代码信息");
    rbc = true;
    return rbc;
}

//输出vct表结构 OK
/* */
bool OutVctTableStructureBeginEnd(short* ptALst)
{
    bool rbc = false;   
    char* GeoVctType;
    char* FeatClassName;
    char* FeatureCode;
    char* FeatureName;

	short ai,LayerType;	
	char* Lfilename;

    //this.ShowMsg(this, "正在输出表结构信息");
    //输出表结构
    f_WriteLine("TableStructureBegin");
    for(int k=1;k<=ptALst[0];k++)
    {   //获取一个工作区
		ai=ptALst[k]; 
		//获取工作区文件名
		Lfilename=_GetAreaFileName(ai);
		//获取图层类型
		LayerType=_GetAreaType(ptALst[k]);
		GeoVctType="UnKown";
		switch(LayerType)
		{
			case REG:
				GeoVctType="Polygon";
				break;
			case LIN:
				GeoVctType="Line";
				break;
			case PNT:
                GeoVctType="Point";
				break;
			default:
				break;
		}        
        FeatClassName =Lfilename;

        FeatureCode =a3u(GeoVctType,"_",i2cp(k));
        FeatureName =FeatureCode;

        //this.ShowMsg(this, "正在输出表结构" + zhfeatclass.GetAliasName + "[" + FeatClassName + "]");
        //获取字段集合
		CATT_STRU *stru;
		_GetAttStru(ai,LayerType,&stru);
		//弹出 [线属性查询]窗体
		/*  
		char* expStr=new char[256];
		if(_InputExpresion(MainWnd,stru,expStr,256,"线属性查询",NULL))
		{
             ShowMsg(expStr);
		}*/
		//
		CINFO_HEAD cinfo=stru->hd;		
		short numbfield=cinfo.numbfield;  //字段个数
             
        f_WriteLine(a3u(FeatClassName , "," , short2cp(numbfield)));     //DLTB,25
		//
        char* FieldTypeStr = "Char";
        short FieldLength = 50;
        short FieldJd = -1;
		CFIELD_HEAD *pfd=stru[0].fldEntry;
        for(int k=0;k<numbfield;k++)
        {				
			//
			char* fdName   =pfd[k].fieldname;     //字段名称
			char  fdtype   =pfd[k].fieldtype;     //字段类型
			short fdlength =pfd[k].msk_leng;      //字段长度
			short fd_digits=pfd[k].point_leng;    //字段小数位数
            switch (fdtype)
            {
                case TEXT_TYPE:
				case STR_TYPE:
                    FieldTypeStr = "Char";
                    FieldLength = fdlength;
                    FieldJd = -1;
                    break;
                case LONG_TYPE:
				case SHORT_TYPE:                
                    FieldTypeStr = "Integer";
                    FieldLength = fdlength;
                    FieldJd = -1;
                    break;
                case FLOAT_TYPE:
                case DOUBLE_TYPE:
                    FieldTypeStr = "Float";
                    FieldLength = fdlength;
                    FieldJd = fd_digits;
                    break;
                case DATE_TYPE:
                    FieldTypeStr = "Date";
                    FieldLength = fdlength;
                    FieldJd = -1;
                    break;
                case BIN_DATA_TYPE:
                    FieldTypeStr = "Varbin";
                    FieldLength = fdlength;
                    FieldJd = -1;
                    break;
                default:
                    FieldTypeStr = "Char";
                    FieldLength = fdlength;
                    FieldJd = -1;
                    break;
            } //end switch
            if (FieldJd != -1)
            {
                f_WriteLine(a7u(fdName , "," , FieldTypeStr , "," , short2cp(FieldLength) , "," , short2cp(FieldJd)));
            }
            else
            {
                f_WriteLine(a5u(fdName , "," , FieldTypeStr , "," , short2cp(FieldLength)));
            }            
		}//end for
        //f_WriteLine("BSM,Integer,12");      //Integer/Char/Float/Date
        //f_WriteLine("TBYBH,Char,9");
        //f_WriteLine("TBBH,Char,9");
    }//end for
	f_WriteLine("TableStructureEnd"); 
	f_WriteLine("");
    //this.ShowMsg(this, "完成输出表结构信息");
    rbc = true;
    return rbc;
}

//输出线坐标 OK 
bool OutVctLineBeginEnd(short ai)
{
    bool rbc = false;
    char* GeoVctType;
    char* FeatClassName;
    char* FeatureCode;
    char* FeatureName;

    //this.ShowMsg(this, "正在输出线坐标信息");
    //输出线坐标
    long i,j,ln;
	D_DOT *lxy; 

	long  len;
	double   x,y;			
	char* tmp;
	short LayerType;	
	char* Lfilename;

    f_WriteLine("LineBegin");
	//获取线层总个数
	_GetLinNum(ai,&i,&ln);
    //获取工作区文件名
	Lfilename=_GetAreaFileName(ai);
	//获取图层类型
	LayerType=_GetAreaType(ai);
	GeoVctType="UnKown";
	switch(LayerType)
	{
		case REG:
			GeoVctType="Polygon";
			break;
		case LIN:
			GeoVctType="Line";
			break;
		case PNT:
            GeoVctType="Point";
			break;
		default:
			break;
	}        
    FeatClassName =Lfilename;

    FeatureCode =a3u(GeoVctType,"_",i2cp(1));
    FeatureName =FeatureCode;

    if (GeoVctType == "Line")
    {
        long lineNum = 0;
        for(i=1;i<ln;i++)  //线要素总个数
		{
			if(_GetLin(ai,i,&lxy,&len,NULL)<=0)
			{
				 continue;
			}           
            lineNum += 1;
            f_WriteLine(l2cp(lineNum));      //第一行序号(目标标识码)
            f_WriteLine(FeatureCode);        //第二行要素代码
            f_WriteLine(FeatureName);        //第三行要素名称
            f_WriteLine("1");                //第四行几何要素段类型(1=折线,2=圆弧,3=圆,4=椭圆,5=光滑曲线,6=B样条曲线,100=间接坐标)

            if(len>0)
			{
                f_WriteLine(l2cp(len));       //第五行点数
                for(j=0;j<len;j++,lxy++)      //线节点
				{					 
					//获取地理坐标
					x=lxy->x; 
					y=lxy->y;
					//写入到文本中
					char* x_s=d2cp(x);
					char* y_s=d2cp(y);								
					tmp=a2u(x_s,",");
					tmp=a2u(tmp,y_s);	
					//
					f_WriteLine(tmp);  //第五行点坐标
				}
            }
            else
            {   //几何对象为空时
                f_WriteLine("0");      //第五行点数                        
            }
            if (lineNum % 50 == 0)
            {
                f_FlushFile();
            }                
        } //end for            
    }//end if    
    f_WriteLine("LineEnd");    
    f_WriteLine("");  
	f_FlushFile();	
    //this.ShowMsg(this, "完成输出线坐标信息");
    rbc = true;
    return rbc;
}

//输出属性值 ??
bool OutVctAttributeBeginEnd(short ai)
{
    bool rbc = false;    
    char* GeoVctType = "";
    char* FeatClassName = "";
    char* FeatureCode = "";
    char* FeatureName = "";

	long i,ln; 

    //this.ShowMsg(this, "正在输出属性值信息");
    //输出属性值
    f_WriteLine("AttributeBegin");
    //获取线层总个数
	_GetLinNum(ai,&i,&ln);
    //获取工作区文件名
	char* Lfilename=_GetAreaFileName(ai);
	//获取图层类型
	short LayerType=_GetAreaType(ai);
	GeoVctType="UnKown";
	switch(LayerType)
	{
		case REG:
			GeoVctType="Polygon";
			break;
		case LIN:
			GeoVctType="Line";
			break;
		case PNT:
            GeoVctType="Point";
			break;
		default:
			break;
	}        
    FeatClassName =Lfilename;

    FeatureCode =a3u(GeoVctType,"_",i2cp(1));
    FeatureName =FeatureCode;
                

    f_WriteLine(FeatClassName);
    if (ln > 0)
    {   //有要素个数>0
        char* AttrLine =NULL;
        char* fdval = NULL;
        long lineNum = 0; 
		CATT_STRU *stru=NULL;
		char *att=NULL;
		short numbfield=0;
		short ret_gt;
        //
        for(i=1;i<ln;i++)  //线要素总个数
		{
            lineNum += 1;
            AttrLine = l2cp(lineNum);
			//获取属性值
			ret_gt=_GetAtt(ai,LayerType,i,&stru,&att);
            short numbfield=stru->hd.numbfield;  //字段个数
			CFIELD_HEAD *pfd=stru[0].fldEntry;
            //
			for(int k=0;k<numbfield;k++)
			{
                fdval=&att[k]; //??
				//_CvtFldToString(stru,att,k,fdval,pfd[k].msk_leng,NULL,NULL);
				if (strlen(AttrLine) <= 0)
                {
                    AttrLine = fdval;
                }
                else
                {
                    AttrLine =a3u(AttrLine,"," , fdval);
                }
			}            
            f_WriteLine(AttrLine);
            if (lineNum % 50 == 0)
            {
                f_FlushFile();
            }                
        }            
    }
    f_WriteLine("TableEnd");
    f_WriteLine("");    
    f_WriteLine("AttributeEnd");    
    //this.ShowMsg(this, "完成输出属性值信息");
    rbc = true;
    return rbc;
}

//获取线层总个数
/*
_GetLinNum(ai,&i,&ln);
f_WriteLine(UnionStr("线总个数:",i2cp(ln)));
for(i=1;i<ln;i++)
{
	 if(_GetLin(ai,i,&lxy,&len,NULL)<=0)
	 {
		 continue;
	 }
	 WriteToLog(i2cp(i));          //线序号
	 f_WriteLine(i2cp(i));
	 for(j=0;j<len;j++,lxy++)      //线节点
	 {
		 //获取窗口坐标
		 //x=(int)((lxy->x-wxy->x0)*wxy->r);
		 //y=(int)((lxy->y-wxy->y0)*wxy->r);
		 //获取地理坐标
		 x=lxy->x;
		 y=lxy->y;
		//写入到文本中
		char* x_s=d2cp(x);
		char* y_s=d2cp(y);								
		tmp=a2u(x_s,",");
		tmp=a2u(tmp,y_s);
		WriteToLog(tmp);
		f_WriteLine(tmp);
	 }
}*/			

//删除线图层的所有要素
//_GetLin(lai,&logN,&n);
//for(i=1;i<n;i++) /*编者注:图元实体号应从1开始*/
//  _DelLin(lai,i);     /*应该是for(i=1;i<=n;i++)*/

//走钟光标
//void WINAPI _StartClockCursor(void);
//void WINAPI _GoingClockCursor(void);
//void WINAPI _EndClockCursor(void);
//void WINAPI _StartWait(void); //开始显示等待光标
//void WINAPI _EndWait(void);   //结束显示等待光标

void Vct_Export()
{	
	_StartClockCursor();
	_GoingClockCursor();
	_StartWait();
	//
	short n;
	WriteToLog_f_delete();
    //TestGetDiskSpace();
	//取打开的工作区数
    n=_GetAreaNumber(AHInst);       
	char* n_str=l2cp(n);
	ShowMsg(n_str);
	//获取当前可执行文件目录
	char* curdir=GetCurDir();
	ShowMsg(curdir);

	//WriteToLog(curdir);
	//获取显示工作区表集合 
	short *ptALst=NULL;              
    if((ptALst=_GetDispAreaListAddr(GrpWnd))!=NULL)
	{    
		if(ptALst==NULL)  return;
		ShowMsg("工作区表不为空");
		WIN_ORG   tmp_wxy;
		
		short ai,LayerType;	
		char* Lfilename;
		if(!_GetWinDispParam(GrpWnd,&tmp_wxy))
		{   //获取窗口显示参数
            return;
		}
		WIN_ORG *wxy=&tmp_wxy;
		char* total_str=i2cp(ptALst[0]);
		char* tt_str=a2u("工作区表总个数:",total_str);
        ShowMsg(tt_str);
		//vct输出
		char* t_fn="dgx.vct";//getfilename_lc(Lfilename,"\\");
        WriteToLog(t_fn);			
		char* tmp_line_path=a2u("c:\\",t_fn);
		WriteToLog(tmp_line_path);
		//
		f_SetFilePath(tmp_line_path);
		f_OpenFile_w();
		OutVctHeadBeginEnd();                 //1输出VCT文件头段			
		OutVctFeatureCodeBeginEnd(ptALst);    //2输出VCT要素代码段
		OutVctTableStructureBeginEnd(ptALst); //3输出VCT表结构段
		//ptALst[0]表示总个数
		for(int k=1;k<=ptALst[0];k++)
        {   //获取一个工作区
			ai=ptALst[k]; 
			//获取工作区文件名
			Lfilename=_GetAreaFileName(ai);
			//-------------------------------
			//获原文件路径的文件名												
			char* t_dir=getdir_lc(Lfilename,"\\");
			::MessageBox(NULL,"执行完毕!","",0);
			//-------------------------------
			//获取图层类型
			LayerType=_GetAreaType(ptALst[k]);
			//输出VCT点,线,面图层的几何图形
			switch(LayerType)
			{
				case LIN:  //线图层
					{
						WriteToLog("线图层");
						WriteToLog(Lfilename);
						//
						OutVctLineBeginEnd(ai);  //输出vct线要素几何图形
						//			
					}
					break;
				case REG:   //面图层
					{
                       WriteToLog("面图层");
					}
					break;
				case PNT:   //点图层
					{

					}
					break;
				default:
					break;
			} //end switch
			//输出属性表
			OutVctAttributeBeginEnd(ai);
		}//end for
		f_CloseFile();
	}
	_EndWait();
	_EndClockCursor();
	ShowMsg("生成完毕!");
}

--the---end----

--vp:hsg

--create date:2012-04-18---

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值