link: http://blog.csdn.net/gm316/archive/2007/10/07/1813634.aspx
void CagGeometrys::AddTrack(CMapControlDefault &mc, hdcGeometryType gt,long button, long shift, long x, long y, double mapX, double mapY)
{
//演示rubber的操作,mc中才提供包装结果track,在vba中应该用rubber
if(e_bUnique)
e_geos.clear();
switch(gt)
{
case gt_Point:
{
IPointPtr pt(__uuidof(Point));
pt->PutCoords(mapX,mapY);
IGeometryPtr *g=new IGeometryPtr;
(*g)=pt;
e_geos.insert(e_geos.end(),g);
}
break;
case gt_Rectangle:
{
IEnvelopePtr env=mc.TrackRectangle();
IGeometryPtr *g=new IGeometryPtr;
(*g)=env;
e_geos.insert(e_geos.end(),g);
}
break;
case gt_Polyline:
{ /*
IPolylinePtr pl=mc.TrackLine();
IGeometryPtr *g=new IGeometryPtr;
(*g)=pl;
e_geos.insert(e_geos.end(),g);
*/
IActiveViewPtr av;
IScreenDisplayPtr sd;
av=mc.GetActiveView();
av->get_ScreenDisplay(&sd);
ISymbolPtr sym;
IGeometryPtr *geo=new IGeometryPtr;
IRubberBandPtr rp(__uuidof(RubberLine));
rp->TrackNew(sd,sym,&(*geo)); //应该可以在track就有symbol效果
e_geos.insert(e_geos.end(),geo);
//转换用QI,应该ok
//IPolylinePtr line;
//line=*geo;
}
break;
case gt_Circle:
{
IPolygonPtr c=mc.TrackCircle();
IGeometryPtr *g=new IGeometryPtr;
(*g)=c;
e_geos.insert(e_geos.end(),g);
}
break;
case gt_Polygon:
{
IPolygonPtr pg=mc.TrackPolygon();
IGeometryPtr *g=new IGeometryPtr;
(*g)=pg;
e_geos.insert(e_geos.end(),g);
}
break;
case gt_Text_Point:
{
textInfo *ti=new textInfo;
IPointPtr pt(CLSID_Point);
pt->PutCoords(mapX,mapY);
ti->geo=pt;
IGetStringDialogPtr gsd(__uuidof(GetStringDialog));
short res;
gsd->DoModal(L"title",L"label",L"",NULL,&res);
CComBSTR bstr;
CString str;
gsd->get_Value(&bstr);
str=bstr;
strcpy(ti->text,str);
e_texts.insert(e_texts.end(),ti);
}
break;
case gt_Text_Polyline:
{
textInfo *ti=new textInfo;
ti->geo=mc.TrackLine();
IGetStringDialogPtr gsd(__uuidof(GetStringDialog));
short res;
gsd->DoModal(L"title",L"label",L"",NULL,&res);
CComBSTR bstr;
CString str;
gsd->get_Value(&bstr);
str=bstr;
strcpy(ti->text,str);
e_texts.insert(e_texts.end(),ti);
}
break;
case gt_Text_Polygon:
{
textInfo *ti=new textInfo;
ti->geo=mc.TrackPolygon(); //可以模拟圆形,矩形等
IGetStringDialogPtr gsd(__uuidof(GetStringDialog));
short res;
gsd->DoModal(L"title",L"label",L"",NULL,&res);
CComBSTR bstr;
CString str;
gsd->get_Value(&bstr);
str=bstr;
strcpy(ti->text,str);
e_texts.insert(e_texts.end(),ti);
}
break;
}
IActiveViewPtr av=mc.GetActiveView();
av->Refresh();
}
void CagGeometrys::Draw(CMapControlDefault &mc)
{
//draw geometry
long i,count;
count=e_geos.size();
for(i=0;i<count;i++)
{
mc.DrawShape((*e_geos[i]),NULL);
}
{
ISelectionTrackerPtr sk;
sk.CreateInstance(__uuidof(EnvelopeTracker));
IActiveViewPtr av=mc.GetActiveView();
IScreenDisplayPtr sd;
av->get_ScreenDisplay(&sd);
IEnvelopePtr env;
count=e_sels.size();
for(i=0;i<count;i++)
{
(*e_sels[i])->get_Envelope(&env);
sk->put_Geometry(env);
sk->Draw(sd,NULL,esriTrackerDominant);
}
}
//文本
count=e_texts.size();
for(i=0;i<count;i++)
{
IMapPtr map=mc.GetMap();
IActiveViewPtr av=mc.GetActiveView();
IScreenDisplayPtr sd;
av->get_ScreenDisplay(&sd);
/* 屏幕中间
ITextSymbolPtr t(__uuidof(TextSymbol));
IFontDispPtr f; //无用途
t->get_Font(&f);
t->put_Size(18.0);
OLE_HANDLE hdc;
sd->get_hDC(&hdc);
sd->StartDrawing(hdc,esriNoScreenCache);
ISymbolPtr s=t;
sd->SetSymbol(s);
IAreaPtr a;
IDisplayTransformationPtr dt;
sd->get_DisplayTransformation(&dt);
IEnvelopePtr e;
dt->get_VisibleBounds(&e);
a=e;
IPointPtr pt;
a->get_Centroid(&pt);
sd->DrawText(pt,L"test");
*/
ITextSymbolPtr t(__uuidof(TextSymbol));
IColorPtr c(__uuidof(RgbColor));
c->put_RGB(RGB(0,0,255));
t->put_Color(c);
IFontDispPtr f; //无用途
t->get_Font(&f);
t->put_Size(18.0);
OLE_HANDLE hdc;
sd->get_hDC(&hdc);
sd->StartDrawing(hdc,esriNoScreenCache);
ISymbolPtr s=t;
sd->SetSymbol(s);
USES_CONVERSION;
//点位置是字符底部中间
sd->DrawText(e_texts[i]->geo,A2W(e_texts[i]->text));
sd->FinishDrawing();
}
}
void CagGeometrys::HitTest(double x, double y)
{
/*
esriGeometryNull = 0
esriGeometryPoint = 1
esriGeometryMultipoint = 2
esriGeometryPolyline = 3
esriGeometryPolygon = 4
esriGeometryEnvelope = 5
esriGeometryPath = 6
esriGeometryAny = 7
esriGeometryMultiPatch = 9
esriGeometryRing = 11
esriGeometryLine = 13
esriGeometryCircularArc = 14
esriGeometryBezier3Curve = 15
esriGeometryEllipticArc = 16
esriGeometryBag = 17
esriGeometryTriangleStrip = 18
esriGeometryTriangleFan = 19
esriGeometryRay = 20
esriGeometrySphere = 21
*/
/*
HRESULT HitTest(
IPoint* QueryPoint,
double searchRadius,
esriGeometryHitPartType geometryPart,
IPoint* hitPoint,
double* hitDistance,
long* hitPartIndex,
long* hitSegmentIndex,
VARIANT_BOOL* bRightSide,
VARIANT_BOOL* bHit
);
*/
e_sels.clear();
esriGeometryType gt;
long i,count=e_geos.size();
for(i=0;i<count;i++)
{
(*e_geos[i])->get_GeometryType(>);
switch(gt)
{
case esriGeometryPoint:
{ //OK,但是被选择的显示方式有问题
IHitTestPtr ht;
IPointPtr pt;
pt=e_geos[i];
ht=pt;
IPointPtr qp(__uuidof(Point));
qp->PutCoords(x,y);
IPointPtr hp(__uuidof(Point));
double hd;
long hpi,hs;
short rs,h;
ht->HitTest(qp,5.0,esriGeometryPartBoundary,hp,&hd,&hpi,&hs,&rs,&h);
if(h==-1)
{
e_sels.insert(e_sels.end(),e_geos[i]);
}
}
break;
case esriGeometryPolyline:
{
IHitTestPtr ht;
IPolylinePtr pl;
pl=e_geos[i];
ht=pl;
IPointPtr qp(__uuidof(Point));
qp->PutCoords(x,y);
IPointPtr hp(__uuidof(Point));
double hd;
long hpi,hs;
short rs,h;
ht->HitTest(qp,5.0,esriGeometryPartBoundary,hp,&hd,&hpi,&hs,&rs,&h);
if(h==-1)
{
e_sels.insert(e_sels.end(),e_geos[i]);
}
}
break;
case esriGeometryEnvelope:
case esriGeometryPolygon:
{
IPointPtr qp(__uuidof(Point));
qp->PutCoords(x,y);
IRelationalOperatorPtr ro;
ro=e_geos[i];
short yes;
ro->Contains(qp,&yes);
if(yes==-1)
{
e_sels.insert(e_sels.end(),e_geos[i]);
}
}
break;
}
}
}
long CagGeometrys::GetSelectCount()
{
return (e_sels.size());
}
void CagGeometrys::ClearSelect()
{
e_sels.clear();
}
BOOL CagGeometrys::DeleteSelect()
{
long i,j,count1,count=e_sels.size();
//sel中不一定是用了geos中顺序,并且选择后可能添加了新的geo
for(i=0;i<count;i++)
{
count1=e_geos.size();
for(j=0;j<count1;j++)
{
if(e_geos[j]==e_sels[i])
{
e_geos.erase(e_geos.begin()+j);
break;
}
}
}
return TRUE;
}
void CagGeometrys::Move(CMapControlDefault &mc)
{
IActiveViewPtr av;
av=mc.GetActiveView();
IScreenDisplayPtr sd;
av->get_ScreenDisplay(&sd);
ISymbolPtr sym;
IGeometryPtr geo=(*e_sels[0]);
IRubberBandPtr rb;
short c;
esriGeometryType gt;
// long i,count=e_sels.size();
// for(i=0;i<count;i++) 每次只可以移动一个shape
{
(*e_sels[0])->get_GeometryType(>);
switch(gt)
{
case esriGeometryPoint:
rb.CreateInstance(CLSID_RubberPoint);
break;
case esriGeometryPolyline:
rb.CreateInstance(CLSID_RubberLine);
break;
case esriGeometryEnvelope:
rb.CreateInstance(CLSID_RubberEnvelope); //移动后图形消失
// rb.CreateInstance(CLSID_RubberPolygon);//无效果
break;
case esriGeometryPolygon: //包括了circle
rb.CreateInstance(CLSID_RubberPolygon);
break;
}
}
if(rb!=NULL)
rb->TrackExisting(sd,sym,geo,&c);
av->Refresh();
}
BOOL CagGeometrys::AddImportPoint(CString sPathFile)
{
FILE *f;
f=fopen(sPathFile,"rt");
if(f==NULL)
{
AfxMessageBox("无法打开指定文件.");
return FALSE;
}
IPointCollectionPtr pc(__uuidof(Multipoint));
IPointPtr pt;
double x,y;
while(1)
{
if(fscanf(f,"%lf %lf",&x,&y)!=2)
break;
pt.CreateInstance(CLSID_Point);
pt->put_X(x);
pt->put_Y(y);
pc->AddPoint(pt);
}
fclose(f);
if(e_bUnique)
e_geos.clear();
IGeometryPtr *g=new IGeometryPtr;
(*g)=pc;
e_geos.insert(e_geos.end(),g);
return TRUE;
}
BOOL CagGeometrys::AddImportPolyline(CString sPathFile)
{
FILE *f;
f=fopen(sPathFile,"rt");
if(f==NULL)
{
AfxMessageBox("无法打开指定文件.");
return FALSE;
}
double x,y;
IPointPtr pt;
IPointCollectionPtr pts(CLSID_Polyline);
while(1)
{
if(fscanf(f,"%lf %lf",&x,&y)!=2)
break;
pt.CreateInstance(CLSID_Point);
pt->put_X(x);
pt->put_Y(y);
pts->AddPoint(pt);
}
fclose(f);
if(e_bUnique)
e_geos.clear();
IGeometryPtr *g=new IGeometryPtr;
(*g)=pts;
e_geos.insert(e_geos.end(),g);
return TRUE;
}
BOOL CagGeometrys::AddImportPolygon(CString sPathFile)
{
FILE *f;
f=fopen(sPathFile,"rt");
if(f==NULL)
{
AfxMessageBox("无法打开指定文件.");
return FALSE;
}
IPolygonPtr pg(CLSID_Polygon);
double x,y;
IPointPtr pt;
IPointCollectionPtr pts(__uuidof(Ring));
while(1)
{
if(fscanf(f,"%lf %lf",&x,&y)!=2)
break;
pt.CreateInstance(CLSID_Point);
pt->put_X(x);
pt->put_Y(y);
pts->AddPoint(pt);
}
fclose(f);
IRingPtr r=pts;
r->Close();
IGeometryCollectionPtr gc=pg;
gc->AddGeometry(r);
if(e_bUnique)
e_geos.clear();
IGeometryPtr *g=new IGeometryPtr;
(*g)=pg;
e_geos.insert(e_geos.end(),g);
return TRUE;
}
BOOL CagGeometrys::AddPoint(double x, double y)
{
if(e_bUnique)
e_geos.clear();
IPointPtr pt(__uuidof(Point));
pt->PutCoords(x,y);
IGeometryPtr *g=new IGeometryPtr;
(*g)=pt;
e_geos.insert(e_geos.end(),g);
return TRUE;
}
BOOL CagGeometrys::AddCircle(double x, double y, double r)
{
if(e_bUnique)
e_geos.clear();
IPointPtr pt(__uuidof(Point));
IConstructCircularArcPtr cca(__uuidof(CircularArc));
pt->PutCoords(x,y);
cca->ConstructCircle(pt,r,-1);
IGeometryPtr *g=new IGeometryPtr;
(*g)=cca;
e_geos.insert(e_geos.end(),g);
return TRUE;
}
2 绘制一条polyline
可以使用AE里面的 IRubberBand 接口画在MapControl上:
IRubberBand rubberLine = new RubberLineClass();
IPolyline polyLine = (IPolyline)rubberLine.TrackNew(pActiveView.ScreenDisplay, null);
//设置图形的样式
m_Symbol = SetDisplaySymbol(polyLine);
//画出图形
pActiveView.ScreenDisplay.StartDrawing(m_QueryMap.ActiveView.ScreenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
pActiveView.ScreenDisplay.DrawPolyline(pGeometry);
pActiveView.Refresh();
pActiveView.ScreenDisplay.FinishDrawing();
通过point构造Segment,再构造path,再构造polyline
用到ISegmentCollection,IPointCollection等接口,帮助里有个例子
The following subs are demonstrating how to create valid polylines efficiently.
A. Geometry type: Polyline
1. createMultipartPolylinePathSegmentCollection: Create a multipart polyline using path via ISegmentCollection.
2. createMultipartPolylinePathPointCollection: Create a multipart polyline using path via IPointCollection.
{
IPoint p1 = this.axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x1,y1);
IPoint p2 = this.axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x2,y2);
IPolyline line = new PolylineClass();
line.FromPoint=p1;
line.ToPoint=p2;
IGeometry lineGeometry = line as IGeometry;
retrun lineGeometry ;
}
private void DrawShape(IGeometry line)
{
pgc.DeleteAllElements();
//定义颜色
//定义线符号
IRgbColor lcolor = Utility.GetRGBColor(btnLColor.BackColor);
ISimpleLineSymbol outline = new SimpleLineSymbolClass();
if(this.txtWidth.Text.Trim()=="")
outline.Width=0;
else
outline.Width=Double.Parse(this.txtWidth.Text);
outline.Color = lcolor;
outline.Style = (esriSimpleLineStyle)(((StringIntObject)this.cbLineStyle.SelectedItem).i);
//定义使用填充符号的面
ILineElement LineE = new LineElementClass();
LineE.Symbol=outline;
IElement pElement = LineE as IElement;
pElement.Geometry=line ;
pgc.AddElement(pElement,0);
axMapControl1.Refresh( esriViewDrawPhase.esriViewGraphics, null,null );
}