delphi操作mapx部分技巧

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Delphi中使用Mapx
目录
一.在地图上创建图层 (1)
二.在符号图元中使用自定义位图 (1)
三.屏幕坐标向地图坐标的转换 (2)
四.查找某一城市 (3)
五.鼠标点击选中一片区域 (3)
六.从数据库绘制MapX地图 (4)
七.MapX使用数据库数据添加专题图 (6)
八.在mapx中画圆 (10)
九.动态加载一个目录下所有图层 (11)
安装好MapX后,选择Delphi的Component->Import Active菜单添加,MapInfo MapX组件。

添加完成后,在ActiveX面板上,将会出来一个TMap控件。

拖一个TMap 控件到工程中改名为MainMap,这样就产生了一个TMap的对象。

一.在地图上创建图层
使用Layers属性的CreateLayer函数来创建一个图层
yers.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:\Program Files\Common Files\MapInfo Shared\MapX Common\CUSTSYMB下,这是MapInfo安装的黩认共享路径。

三.屏幕坐标向地图坐标的转换
procedure TMapForm.Map1MouseUp(Sender:TObject;
Button:TMouseButton;Shift:TShiftState;X,Y:Integer);
var
lon,lat:Double;
singleX,singleY:Single;
fs:CMapXFeatures;
pnt:CMapXPoint;
name:String;
begin
if Map1.CurrentTool=miArrowTool then
begin
pnt:=CoPoint.Create;
singleX:=X;
singleY:=Y;
Map1.ConvertCoord(singleX,singleY,lon,
lat,miScreenToMap);
pnt.Set_(lon,lat);
fs:=yers.
Item('US Top20Cities').SearchAtPoint(pnt);
if fs.Count>0then
begin
name:=fs.Item(1).Name;
Application.MessageBox(PChar(name),'Info',0)
end
else
Application.MessageBox('Nothing found','Nope',0);
end;
end;
备注:
获取一个图元时最好用Layer.GetFeatureByID(FeatureKey);
四.查找某一城市
procedure TForm2.SearchForCapital(Capital:String);
var
FoundF:FindFeature;
//在小城市层查
begin
FoundF:=yers.Item['US Minor Cities'].Find.Search(Capital, EmptyParam);
//在us minor cities层中查找capital
if(FoundF.FindRC mod10)=1then
begin
yers.Item['US Minor Cities'].Selection.Replace(FoundF);
Map1.Zoom:=60;//60英里
Map1.CenterX:=FoundF.CenterX;
Map1.CenterY:=FoundF.CenterY;
end
else
Application.MessageBox('No exact match found.','Nope',0);
end;
五.鼠标点击选中一片区域
procedure TForm2.Map1ToolUsed(ASender:TObject;ToolNum:Smallint;X1, Y1,
X2,Y2,Distance:Double;Shift,Ctrl:WordBool;
var EnableDefault:WordBool);
var
ftrs:Features;//CMapXFeatures;
newJersey:FindFeature;//CMapXFindFeature;
usaLayer:Layer;//CMapXLayer;
pt:Point;
begin
if ToolNum=miSelectTool then
begin
pt:=CoPoint.Create;
pt.Set_(X1,Y1);
usaLayer:=yers.Item['USA'];
newJersey:=usaLayer.Find.Search('NY',EmptyParam);
//找到ny500英里之内的区域
ftrs:=usaLayer.SearchWithinDistance(pt,500,miUnitMile, miSearchTypePartiallyWithin);
mon(usaLayer.SearchWithinDistance(newJersey,500,miUnitMile, miSearchTypePartiallyWithin));
usaLayer.Selection.Replace(ftrs);//选中
end;
end;
六.从数据库绘制MapX地图
这里提供的是一种更为高效的从数据库绘制MapX地图的方法,我在数据库中建立了如下的数据表:
表名称:Xunit
ID:字符串//用于唯一标识各个图元,也可以是数字类型的
NAME:字符串//图元的名称
X:浮点数//图元横坐标
Y:浮点数//图元纵坐标
代码清单:
//aqXUnit是一个TADOQuery,其中SQL语句为“SELECT*FROM XUNIT”。

procedure TfrmMain.DrawLayerFromDB;
var
oBLayer:BindLayer;
SearchLayer:Layer;
ds:Dataset;
begin
//使用这个过程必须保证aqXUnit表已经打开!
if not aqXUnit.Active then
begin
GiveMsg('系统基础表没有打开!');//调用自定义提示方法
exit;
end;
oBLayer:=coBindLayer.Create;
yerName:='ARTEMIS';
yerType:=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:=yers.Item('ARTEMIS');
//字体颜色
belProperties.Style.TextFontColor:=miColorPurple;
belProperties.Style.TextFontHalo:=true;
belProperties.Style.TextFontBackColor:=miColorWhite;
//设置图元显示的标签
belProperties.Dataset:=ds;
belProperties.DataField:=ds.Fields.Item('NAME');
belZoom:=true;
//设置图层缩放比例范围
searchLayer.ZoomMin:=0;
searchLayer.ZoomMax:=200;
searchLayer.ZoomLayer:=true;
//设置标签缩放比例范围
belZoomMin:=0;
belZoomMax:=200;
belZoom:=true;
//自动标记图元
searchLayer.AutoLabel:=true;
end;
七.MapX使用数据库数据添加专题图
OBJECT.Add([Type],[Field],[Name],[ComputeTheme])
OBJECT Represents a Themes object.
Type Specifies the type of thematic map to create.This takes a ThemeTypeConstants value.This is an optional parameter,and if not specified(or specified as miThemeAuto),MapX will attempt to choose a good default based on the number of fields passed in as well as what other theme types are already being displayed.If MapX cannot choose a default theme type,an error is generated.
Field(s)Specifies the field or fields to thematically map.A field can be specified by name,index,or by a Field object.If you are creating a theme using multiple variables(such as a bar chart or pie chart),pass in a Fields collection or an array of field names,indexes,or Field objects.This is an optional parameter, and if not specified,MapX uses the first numeric field of the Dataset.
Name Specifies the name of the thematic map.This is a String parameter.This is an optional parameter,and if not specified,MapX generates a name such as StatesBySales.
ComputeTheme Boolean.The default value is True which will calculate the theme from the table data.If the value is set to False an invisible theme object will be created with10ranges for IndividualValue themes and5ranges for Ranged themes. You can then manually set the minimum and maximum values to define the theme with Theme.DataMin and Theme.DataMax.For ranged themes you can manually set the theme ranges or calculate equal size ranges determined by the minimum(Theme.DataMin) and maximum(Theme.DataMax)values.
关于专题图的风格共有以下几种:
miThemeRanged=0
miThemeBarChart=1
miThemePieChart=2
miThemeGradSymbol=3
miThemeDotDensity=4
miThemeIndividualValue=5
miThemeAuto=6
miThemeNone=9
下面是我写的部分代码:
unit Main;
interface
uses
Windows,Messages,{略去一部分}SysUtils,Variants,Classes;
type
TfrmMain=class(TForm)
mapMain:TMap;{地图控件}
private
{Private declarations}
ThemesList:TStringList;{用来保存多个专题图的名称列表} public
{Public declarations}
procedure ToAddThemes(style:integer;TheName:string);{添加专题图} procedure ToDeleteThemes;{删除专题图}
end;
var
frmMain:TfrmMain;
implementation
{$R*.dfm}
{略去其他功能代码}
{
添加专题图,参数style表示专题图风格,TheName表示图例标题
}
procedure TfrmMain.ToAddThemes(style:integer;TheName:string);
function DefaultName:string;{用来生成一唯一的名称}
begin
{我用的方法是取一个当前时间,两次调用本函数的时间间隔应该不会少于0.5秒,所以这个方法在这个项目中可以取得唯一的名称}
Result:='YYT'+FormatDateTime('YYYYMMDDHHNNSSzzz',now);
end;
var
flds:array of string;{字段列表}
oBLayer:BindLayer;{绑定图层}
ds:Dataset;{MapX数据集}
i:integer;{循环变量}
thm:theme;{MapX专题图}
str:string;{用于保存字符串}
begin
{aqThemes可以是一个ADOQuery或者ADOTable,我使用的是ADOQuery。

在这个ADOQuery中前四个字段分别是:
ID(唯一的数字或者字符串,一般为编号),
NAME(字符串,要素的标签),
X(浮点数,要素的经度或者横坐标),
Y(浮点数,要素的纬度或者纵坐标)。

后面的其它字段都是数字类型,用来表示相关的数据。

}
if not aqThemes.Active then
begin
dmData.GiveMsg('系统基础表没有打开!');
exit;
end;
try
{取一个唯一的名字,}
str:=DefaultName;
{设置绑定图层的属性}
oBLayer:=coBindLayer.Create;
progress.StepPlus(2);
yerName:=str;
yerType:=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);
for i:=3to aqThemes.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;
{
删除专题图,我采用的方法是删除所有专题图
}
procedure TfrmMain.ToDeleteThemes;
var
i:integer;{循环变量}
begin
for i:=0to ThemesList.Count-1do{循环所有添加了的专题图}
begin
{删除数据集}
mapMain.Datasets.Remove(ThemesList.Strings[i]);
{删除专题图}
yers.Remove(ThemesList.Strings[i]);
{如果只想删除某一个专题图,不用循环就行了}
end;
{此时已经没有专题图了,将删除专题图按钮隐藏}
btnDeleteThemes.Visible:=false;
{清除专题图名称列表}
ThemesList.Clear;
end;
//...
end.
八.在mapx中画圆
var
Style:CMapXStyle;
f:CMapXFeature;
pt:Point;
begin
yers.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.FeatureFactory.CreateCircularRegion(miCircleTypeMap,pt,0.2,miUnitKilometer,emptyPa ram,Style);
yers.Item('Temp').AddFeature(f,EmptyParam);
end;
九.动态加载一个目录下所有图层
var path,fileName:string;
myLayerInfo:LayerInfo;
hFindFile:Cardinal;
FindFileData:WIN32_FIND_DATA;
begin
path:=ExtractFilePath(Application.ExeName)+'map\';
ChDir(path);
hFindFile:=FindFirstFile('*.TAB',FindFileData);//找到第一个扩展名为tab的文件
if hFindFile<>windows.INVALID_HANDLE_VALUE then
begin
repeat
filename:=FindFileData.cFileName;
{在这里可以实现对当前文件的处理,比如文件的解密等功能}
try
myLayerInfo:=CoLayerInfo.Create;
myLayerInfo.Type_:=miLayerInfoTypeTab;
myLayerInfo.AddParameter('FileSpec',path+filename);
myLayerInfo.AddParameter('Name',ExtractFileName(fileName));
yers.Add(myLayerInfo,EmptyParam);//加载图层
except
end;
until(FindNextFile(hFindFile,FindFileData)=false);
WindowS.FindClose(hFindFile);;
end;
end;。

相关文档
最新文档