delphi操作mapx部分技巧.docx
《delphi操作mapx部分技巧.docx》由会员分享,可在线阅读,更多相关《delphi操作mapx部分技巧.docx(16页珍藏版)》请在冰豆网上搜索。
delphi操作mapx部分技巧
Delphi中使用Mapx
目录
一.在地图上创建图层-1-
二.在符号图元中使用自定义位图-1-
三.屏幕坐标向地图坐标的转换-2-
四.查找某一城市-3-
五.鼠标点击选中一片区域-3-
六.从数据库绘制MapX地图-4-
七.MapX使用数据库数据添加专题图-6-
八.在mapx中画圆-10-
九.动态加载一个目录下所有图层-11-
安装好MapX后,选择Delphi的Component->ImportActive菜单添加,MapInfoMapX组件。
添加完成后,在ActiveX面板上,将会出来一个TMap控件。
拖一个TMap控件到工程中改名为MainMap,这样就产生了一个TMap的对象。
一.在地图上创建图层
使用Layers属性的CreateLayer函数来创建一个图层
MainMap.Layers.CreateLayer(Name,[FileSpec],[Position],[KeyLength],[CoordSys]);
参数说明:
Name:
指定图层的名称
FileSpec:
所创建图层的路径名。
如'c:
\china.tab'
Position:
它在图层列表中的初始位置.(其实就是在图层列表中的一个序列号)
CoorSys:
指定存储新图层的坐标系。
附:
图层类型参数:
miLayerTypeNormal
miLayerTypeRaster
miLayerTypeSeamless
miLayerTypeUnknown
miLayerTypeUserDraw
miLayerTypeDrilldown
FeatureFactory对象的方法使您可以创建新的地图图元,也可通过对现有图元执行操作(例如缓冲区)来创建图元。
以下是FeatureFactory对象的方法:
BufferFeatures
CombineFeatures
CreateArc
CreateCircularRegion
CreateEllipticalRegion
CreateLine
CreateRegion
CreateSymbol
CreateText
EraseFeature
IntersectFeatures
IntersectionPoints
IntersectionTest
二.在符号图元中使用自定义位图
定义一个cs:
CMapXStyle 做为图元的样式属性设置
cs:
=coStyle.Create;
cs.SymbolType:
=miSymbolTypeBitmap;
cs.SymbolBitmapName:
='HOUS2-32.BMP';
cs.SymbolBitmapSize:
=40;
注意:
自定义的位图一定要放到C:
\ProgramFiles\CommonFiles\MapInfoShared\MapX Common\CUSTSYMB下,这是MapInfo安装的黩认共享路径。
三.屏幕坐标向地图坐标的转换
procedureTMapForm.Map1MouseUp(Sender:
TObject;
Button:
TMouseButton;Shift:
TShiftState;X,Y:
Integer);
var
lon,lat:
Double;
singleX,singleY:
Single;
fs:
CMapXFeatures;
pnt:
CMapXPoint;
name:
String;
begin
ifMap1.CurrentTool=miArrowToolthen
begin
pnt:
=CoPoint.Create;
singleX:
=X;
singleY:
=Y;
Map1.ConvertCoord(singleX,singleY,lon,
lat,miScreenToMap);
pnt.Set_(lon,lat);
fs:
=Map1.Layers.
Item('USTop20Cities').SearchAtPoint(pnt);
iffs.Count>0then
begin
name:
=fs.Item
(1).Name;
Application.MessageBox(PChar(name),'Info',0)
end
else
Application.MessageBox('Nothingfound','Nope',0);
end;
end;
备注:
获取一个图元时最好用Layer.GetFeatureByID(FeatureKey);
四.查找某一城市
procedureTForm2.SearchForCapital(Capital:
String);
var
FoundF:
FindFeature;
//在小城市层查
begin
FoundF:
=Map1.Layers.Item['USMinorCities'].Find.Search(Capital,EmptyParam);//在usminorcities层中查找capital
if(FoundF.FindRCmod10)=1then
begin
Map1.Layers.Item['USMinorCities'].Selection.Replace(FoundF);
Map1.Zoom:
=60;//60英里
Map1.CenterX:
=FoundF.CenterX;
Map1.CenterY:
=FoundF.CenterY;
end
else
Application.MessageBox('Noexactmatchfound.','Nope',0);
end;
五.鼠标点击选中一片区域
procedureTForm2.Map1ToolUsed(ASender:
TObject;ToolNum:
Smallint;X1,Y1,
X2,Y2,Distance:
Double;Shift,Ctrl:
WordBool;
varEnableDefault:
WordBool);
var
ftrs:
Features;//CMapXFeatures;
newJersey:
FindFeature;//CMapXFindFeature;
usaLayer:
Layer;//CMapXLayer;
pt:
Point;
begin
ifToolNum=miSelectToolthen
begin
pt:
=CoPoint.Create;
pt.Set_(X1,Y1);
usaLayer:
=Map1.Layers.Item['USA'];
newJersey:
=usaLayer.Find.Search('NY',EmptyParam);
//找到ny500英里之内的区域
ftrs:
=usaLayer.SearchWithinDistance(pt,500,miUnitMile,miSearchTypePartiallyWithin);
ftrs.Common(usaLayer.SearchWithinDistance(newJersey,500,miUnitMile,miSearchTypePartiallyWithin));
usaLayer.Selection.Replace(ftrs);//选中
end;
end;
六.从数据库绘制MapX地图
这里提供的是一种更为高效的从数据库绘制MapX地图的方法,我在数据库中建立了如下的数据表:
表名称:
Xunit
ID:
字符串//用于唯一标识各个图元,也可以是数字类型的
NAME:
字符串//图元的名称
X:
浮点数//图元横坐标
Y:
浮点数//图元纵坐标
代码清单:
//aqXUnit是一个TADOQuery,其中SQL语句为“SELECT*FROMXUNIT”。
procedureTfrmMain.DrawLayerFromDB;
var
oBLayer:
BindLayer;
SearchLayer:
Layer;
ds:
Dataset;
begin
//使用这个过程必须保证aqXUnit表已经打开!
ifnotaqXUnit.Activethen
begin
GiveMsg('系统基础表没有打开!
');//调用自定义提示方法
exit;
end;
oBLayer:
=coBindLayer.Create;
oBLayer.LayerName:
='ARTEMIS';
oBLayer.LayerType:
=miBindLayerTypeXY;//必须使用这个参数才能绑定XY坐标
oBLayer.RefColumn1:
='X';//第一个参数必须指定为横坐标
oBLayer.RefColumn2:
='Y';//纵坐标
//添加数据集
ds:
=mapMain.Datasets.Add(12,//数据集类型,这是miDataSetADO,即ADO专用的
aqXUnit.Recordset,//使用这个方法获得ADO中的_Recordset类型
'DS_SK',//数据集名称
'ID',//传入的是Xunit表中的字段ID的名称
EmptyParam,
oBLayer,//BindLayer
EmptyParam,
EmptyParam);
//下边将设置新图层的各项属性
searchLayer:
=mapMain.Layers.Item('ARTEMIS');
//字体颜色
searchLayer.LabelProperties.Style.TextFontColor:
=miColorPurple;
searchLayer.LabelProperties.Style.TextFontHalo:
=true;
searchLayer.LabelProperties.Style.TextFontBackColor:
=miColorWhite;
//设置图元显示的标签
searchLayer.LabelProperties.Dataset:
=ds;
searchLayer.LabelProperties.DataField:
=ds.Fields.Item('NAME');
searchLayer.LabelProperties.LabelZoom:
=true;
//设置图层缩放比例范围
searchLayer.ZoomMin:
=0;
searchLayer.ZoomMax:
=200;
searchLayer.ZoomLayer:
=true;
//设置标签缩放比例范围
searchLayer.LabelProperties.LabelZoomMin:
=0;
searchLayer.LabelProperties.LabelZoomMax:
=200;
searchLayer.LabelProperties.LabelZoom:
=true;
//自动标记图元
searchLayer.AutoLabel:
=true;
end;
七.MapX使用数据库数据添加专题图
OBJECT.Add([Type],[Field],[Name],[ComputeTheme])
OBJECTRepresentsaThemesobject.
TypeSpecifiesthetypeofthematicmaptocreate.ThistakesaThemeTypeConstantsvalue.Thisisanoptionalparameter,andifnotspecified(orspecifiedasmiThemeAuto),MapXwillattempttochooseagooddefaultbasedonthenumberoffieldspassedinaswellaswhatotherthemetypesarealreadybeingdisplayed.IfMapXcannotchooseadefaultthemetype,anerrorisgenerated.
Field(s)Specifiesthefieldorfieldstothematicallymap.Afieldcanbespecifiedbyname,index,orbyaFieldobject.Ifyouarecreatingathemeusingmultiplevariables(suchasabarchartorpiechart),passinaFieldscollectionoranarrayoffieldnames,indexes,orFieldobjects.Thisisanoptionalparameter,andifnotspecified,MapXusesthefirstnumericfieldoftheDataset.
NameSpecifiesthenameofthethematicmap.ThisisaStringparameter.Thisisanoptionalparameter,andifnotspecified,MapXgeneratesanamesuchasStatesBySales.
ComputeThemeBoolean.ThedefaultvalueisTruewhichwillcalculatethethemefromthetabledata.IfthevalueissettoFalseaninvisiblethemeobjectwillbecreatedwith10rangesforIndividualValuethemesand5rangesforRangedthemes.YoucanthenmanuallysettheminimumandmaximumvaluestodefinethethemewithTheme.DataMinandTheme.DataMax.Forrangedthemesyoucanmanuallysetthethemerangesorcalculateequalsizerangesdeterminedbytheminimum(Theme.DataMin)andmaximum(Theme.DataMax)values.
关于专题图的风格共有以下几种:
miThemeRanged=0
miThemeBarChart=1
miThemePieChart=2
miThemeGradSymbol=3
miThemeDotDensity=4
miThemeIndividualValue=5
miThemeAuto=6
miThemeNone=9
下面是我写的部分代码:
unitMain;
interface
uses
Windows,Messages,{略去一部分}SysUtils,Variants,Classes;
type
TfrmMain=class(TForm)
mapMain:
TMap;{地图控件}
private
{Privatedeclarations}
ThemesList:
TStringList;{用来保存多个专题图的名称列表}
public
{Publicdeclarations}
procedureToAddThemes(style:
integer;TheName:
string);{添加专题图}
procedureToDeleteThemes;{删除专题图}
end;
var
frmMain:
TfrmMain;
implementation
{$R*.dfm}
{略去其他功能代码}
{
添加专题图,参数style表示专题图风格,TheName表示图例标题
}
procedureTfrmMain.ToAddThemes(style:
integer;TheName:
string);
functionDefaultName:
string;{用来生成一唯一的名称}
begin
{我用的方法是取一个当前时间,两次调用本函数的时间间隔应该不会少于0.5秒,
所以这个方法在这个项目中可以取得唯一的名称}
Result:
='YYT'+FormatDateTime('YYYYMMDDHHNNSSzzz',now);
end;
var
flds:
arrayofstring;{字段列表}
oBLayer:
BindLayer;{绑定图层}
ds:
Dataset;{MapX数据集}
i:
integer;{循环变量}
thm:
theme;{MapX专题图}
str:
string;{用于保存字符串}
begin
{aqThemes可以是一个ADOQuery或者ADOTable,我使用的是ADOQuery。
在这个ADOQuery中前四个字段分别是:
ID(唯一的数字或者字符串,一般为编号),
NAME(字符串,要素的标签),
X(浮点数,要素的经度或者横坐标),
Y(浮点数,要素的纬度或者纵坐标)。
后面的其它字段都是数字类型,用来表示相关的数据。
}
ifnotaqThemes.Activethen
begin
dmData.GiveMsg('系统基础表没有打开!
');
exit;
end;
try
{取一个唯一的名字,}
str:
=DefaultName;
{设置绑定图层的属性}
oBLayer:
=coBindLayer.Create;
progress.StepPlus
(2);
oBLayer.LayerName:
=str;
oBLayer.LayerType:
=miBindLayerTypeXY;
oBLayer.RefColumn1:
='X';
oBLayer.RefColumn2:
='Y';
ds:
=mapMain.Datasets.Add(12,
aqThemes.Recordset,
str,
'ID',
EmptyParam,
oBLayer,
EmptyParam,
EmptyParam);
{组织专题图现实的数据字段,存储在字符串数组中}
SetLength(flds,aqThemes.Fields.Count-3);
fori:
=3toaqThemes.Fields.Count-1do
begin
flds[i-3]:
=aqThemes.Fields.Fields[i].FieldName;
end;
{实际添加专题图的过程}
thm:
=ds.Themes.Add(style,flds,DefaultName,EmptyParam);
{设置专题图图例标题}
thm.Legend.Title:
=TheName;
{记录新添加的专题图名称}
ThemesList.Add(str);
{btnDeleteThemes是一个在本窗口上的按钮,用来删除专题图,
添加专题图后就将他显示出来,如果删除了全部专题图就将他隐藏}
btnDeleteThemes.Visible:
=true;
except
GiveMsg('创建专题图失败!
');{自定义过程,给出出错提示}
end;
end;
{
删除专题图,我采用的方法是删除所有专题图
}
procedureTfrmMain.ToDeleteThemes;
var
i:
integer;{循环变量}
begin
fori:
=0toThemesList.Count-1do{循环所有添加了的专题图}
begin
{删除数据集}
mapMain.Datasets.Remove(ThemesList.Strings[i]);
{删除专题图}
mapMain.Layers.Remove(ThemesList.Strings[i]);
{如果只想删除某一个专题图,不用循环就行了}
end;
{此时已经没有专题图了,将删除专题图按钮隐藏}
btnDeleteThemes.Visible:
=false;
{清除专题图名称列表}
ThemesList.Clear;
end;
//...
end.
八.在mapx中画圆
var
Style:
CMapXStyle;
f:
CMapXFeature;
pt:
Point;
begin
Map1.ControlInterface.Layers.CreateLayer('temp',emptyparam,1,emptyparam,emptyparam);
Style:
=Map1.DefaultStyle.Clone;
Style.RegionPattern:
=miPatternNoFill;
Style.RegionColor:
=255;
Style.RegionBorderColor:
=125;
Style.RegionBorderWidth:
=2;
Style.RegionBorderStyle:
=1;
pt:
=CoPoint.Create;
pt.Set_(122.8,40.8);
map1.Zoom:
=0.5;
map1.CenterX:
=pt.X;
map1.CenterY:
=pt.Y;
f:
=Map1.Feature