mapxtreme开发手册

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

目录
MapXtreme for Java开发教程1 (2)
专题一:怎样在应用中创建地图 (2)
专题二:怎样操作地图---控制地图显示 (5)
专题三:怎样进行空间特征值的搜索 (7)
专题四:怎样对空间特征值对象编辑 (13)
专题五:怎样进行专题分析 (15)
专题六:怎样进行数据绑定---将数据库中的属性数据与地图进行动态连结 (24)
专题七:怎样实现GPS监控 (25)
专题八:怎样调用空间数据库中的地图 (28)
专题九:怎样快速响应多并发用户远程数据库数据请求 (32)
专题十:怎样将影像图与矢量图进行叠加 (34)
MapXtreme for Java开发教程1
概述
MapXtreme for Java(以下简称MXTJ)是基于J2EE技术、服务器端的为创建Web地图服务应用的市场上第一个100%Java跨平台解决方案,使用它可实现瘦客户机/服务器、中等客户机/服务器、胖客户机/服务器三种Web GIS模式。

MXTJ主要由MapXtremeServlet、MapJ、Renderers、Data Providers四部分构成。

MapXtremeServlet是系统的地图服务供给者,它提供如下服务:1 提供栅格地图数据服务,2 提供矢量地图数据服务,3 提供图元文件数据服务(例:tab表里的属性信息);
MapJ位于Mapxtreme客户端应用程序开发包API的最顶端作用有二:1 管理地图集的各种状态(例:地图中心位置、地图视野、地图坐标系等),2通过向MapxtremeServlet服务实例转发客户请求获得Servl et响应的数据和图片;
Renderer用来生成返回客户端地图数据的组件,有四种:LocalRenderer、MapXtremeImageRenderer、.In tra-Servlet Container Renderer、Composite Renderer。

使用MapXtremeImageRender可以在远程产生地图图像,包含MapJ的应用程序和远程一个MapXtremeServlet实例通讯,产生地图图像;LocalRende r将地图输出为Java2D Graphics2D对象,所有的Render在客户端产生,也即所谓地图的矢量传输方式;使用IntraServletContainerRenderer不需socket connection,从而MapXtremeSevlet将地图直接传回给客户端;Composite Renderer将地图分为动态与静态图层,当需要更新地图时,可只更新动态图层,而静态图层仅生成一次。

Data Provider是Layer(图层)对象的内部对象,它不是直接由用户创建的,但是它的描述是对图层的定义。

要描述Data Provider通过如下接口:TableDescHelper –描述数据;DataProviderHelpe
r –定义数据的源;ataProviderRef –描述获取数据的方式。

专题一:怎样在应用中创建地图
专题一:怎样在应用中创建地图?
创建Map步骤:
n 创建MapJ 对象
n 加载地图数据
n 设置地图尺寸
n 生成图片
以下分别描述:
1. 初始化地图对象
执行:MapJ m_mapj = new MapJ();
myMap = new MapJ();
2. 加载地图数据
可以打开GeoSet(*.gst)或MapDefinition(*.mdf )文件加载地图数据。

MapXtreme没有默认的地图数据,所以必须人工加载地图数据。

加载GeoSet
myMap.loadGeoset(geosetName, dataDir, servletURL);
其中:
geosetName:geoset的完整文件名(包括路径);
dataDir:geoset中引用的tab地图文件的位置;
servletURL:mapxtremeservlet的路径,如果MapJ使用L ocalDataProviderRef,servlet URL可以为NULL。

示例:
myMap.loadGeoset("c:\\mapxtreme\\maps\\world.gst",
"c:\\mapxtreme\\maps",
"http://localhost:8080/mapxtreme40/servlet/mapxtreme";);
加载Map Definition
m_mapj.loadMapDefinition(m_mapPath);
可以加载保存在文件中的地图定义(*.mdf)或者数据库中的地图定义记录(record)。

首先要创建MapDefContainer,有两种情况:
地图定义在文件中:
MapDefContainer mdc = new FileMapDefContainer(dir)
示例:
MapDefContainer mdc = new FileMapDefContainer("c:\\mapxtreme\maps")
地图定义在数据库中:
MapDefContainer mdc = new JDBCMapDefContainer(driver,url, use
r,
passwo rd)
其中,driver,url,user,password都是数据库连接的参数。

下面的示例是使用Oracle Spatial MapRefContainer,地图定义保存在数据库的表中:
OraSoMapDefContainer mdc =
new OraSoMapDefContainer("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@machinename: 1521:dbSid",
"username", "password", "tableName", "Name",
"Map_Definition");
然后加载地图定义:
myMap.loadMapDefinition(mapDefContainer, name)
name 是地图定义的名字,如:
myMap.loadMapDefinition(mdc, "Asia");
3. 设置图象尺寸
输出地图图像前需要设置地图尺寸,设置方法:MapJ.setDeviceBounds().,单位是象素。

示例:
myMap.setDeviceBounds(new DoubleRect(0, 0, 800, 600));
4. 生成图片
生成图片需要一下几步:
n 指定MapXtremeServlet
String mapxtremeServletUrl = "http://localhost:8080/mapxtreme47/mapxtreme";;
n 创建ImageRequestComposer
ImageRequestComposer imageRC =ImageRequestComposer.create(myMap, 256, Color.blue,"image/ gif");
表示图片是256色背景为蓝色的GIF图。

n 创建ImageRender
MapXtremeImageRenderer renderer = new MapXtremeImageRenderer(mapxtremeServletURL);
n 生成图片
返回图像的唯一办法就是使用Render对象。

Renderer.render(imageRC);
Renderer.toFile("comp.gif");
此外,还可以使用toStream,toImage方法将图像返回。

如果使用MapJ直接获取地图数据并生成图片,则使用LocalRender而不是MapXtremeImageRender。

MapXt remeImageRender和LocalRender将在后面专门章节介绍。

专题二:怎样操作地图---控制地图显示
专题二:怎样操作地图---控制地图显示?
看到地图图像后,你可能需要查看地图的其他部分,看看整体或地图细节。

下面介绍一些控制地图显示的方法。

1. 设置地图视野(Zoom)
Zoom值是地图的横向跨度,单位有地图的距离单位决定。

设置zoom可以放大或缩小地图。

当地图加载时,zoom就被设定了。

改变zoom的方法是setZoom()。

示例:
// Assuming that the current distance units are kilometers, this command will se t the //map zoom to 500 kilometers.
myMap.setZoom(500);
2.设置地图中心
有时会将地图中心定位在找到的目标上或将中心定位在鼠标所点击的图像上某一点。

这时需要设置地图中心。

设置地图中心的方法是setCenter()。

下面的示例实现了将地图中心定位在鼠标点击的某一点。

示例:
// 创建屏幕坐标的Point对象
screenpoint = new DoublePoint(event.getX(),event.getY());
// 将屏幕坐标转换为地理坐标
worldpoint = myMap.transformScreenToNumeric(screenpoint);
// 设置地图中心
myMap.setCenter(worldpoint);
3.设置地图边界
地图边界不是图象的边界,而是地图坐标系的边界,所有的地图操作都在这个边界内进行。

设置地图边界有两种方法:
方法1:
给定边界的左下角和右上角,设定边界。

DoubleRect bounds = new DoubleRect(-180,-90,180,90);
myMap.setBounds(bounds);
方法2:
给定地图的中心,宽度和高度,设定边界。

DoubleRect bounds = new DoubleRect(new DoublePoint(0,0),360,180);
myMap.setBounds(bounds);
4.设置地图投影
坐标数据存储在server\mapinfow.prj文件中,包含上百种投影。

可以按照如下方法,使用PRJ文件设置投影:
String csProj = new String("\"Azimuthal Equidistant(North Pole)\", 5, 62, 7, 0, 9 0, 90");
CoordSys ts = CoordSys.createFromPRJ(csProj);
myMap.setDisplayCoordSys(ts);
也可以用createFromMapBasic读取MapBasic字符串来设置投影。

5. 设置地图距离单位
示例:
distUnit = LinearUnit.kilometer;
myMap.setDistanceUnits(distUnit);
6. 添加图层
使用Layers.add方法(详见下一章)向地图添加额外的图层,该图层可以来自文件或数据库。

MapXtreme使用DataProvider来管理这些信息。

专题三:怎样进行空间特征值的搜索
1. Search介绍
有时可能做一些搜索,如搜索配送中心周围的零售店。

MapXtreme提供了丰富的搜索功能。

搜索的结果可以转换为被选中状态,从而显示在地图上。

Search是Layer对象的方法,有:
• searchAll
• searchWithinRadius
• searchWithinRegion
• searchWithinRectangle
• searchAtPoint
• searchByAttribute
• searchByPrimaryKey
使用这些查询都需要给出要返回的字段集合和执行的查询动作。

返回的字段集合需要放在Vector对象中。

下面的例子返回的是表中所有的字段:
//Assume myLayer is a Layer object.
TableInfo myTableInfo = myLayer.getTableInfo( );
Vector columnNames = new Vector( );
int columnCount = myTableInfo.getColumnCount( );
String col;
for (int j=0; j<columnCount; j++)
{
col = myTableInfo.getColumnName(j);
columnNames.addElement(col);
}
在默认情况下,执行查询时后得到的FeatureSet包含Geometry,Rendition,LabelRendi tion,PrimaryKey,raster Data等,所以需要使用QueryParams 类来过滤这些信息,以提高程序的性能。

进行查询时可以通过QueryParams指定查询类型SearchType。

Mbr表示搜索最小外接矩形和搜索范围相交的图元;patial表示搜索和搜索范围相交的图元;entire表示搜索完全在搜索范围的的图元。

下面代码示例如何使用QueryParams:
QueryParams qp = new QueryParams(bGeometry,bRendition,bPrimarykey,bLabelPoint,bRasterInf o,bLabelRendition, SearchType.entire);
下面示例了如何过滤信息:
// find all Features entirely within a given search region, return a single Att ribute column //and noRendition information.
Vector cols = new Vector();
cols.addElement(“County”);
Feature searchFeature =mapj.getFeatureFactory().createRegion(points, rend,attribs,nul l);
QueryParams queryParams = new QueryParams(true, false,true,true, true, true, SearchT ype.entire);
FeatureSet fs = layer.searchWithinRegion(cols,searchFeature.getGeometry(), queryParam s);
2. Search方法
: searchAll
示例:
//Assume fs is a FeatureSet object.Assume columnNames is a vector of the column s //to be returned.Assume qp is the QueryParams object.Assume myLayer is a Laye r //object.
try
{
fs = myLayer.searchAll(columnNames,qp);
}
catch(exception e)
{
e.printStackTrace();
}
:==>searchWithinRadius
示例:
//Assume fs is a FeatureSet object. Assume columnNames is a vector of the desir ed //columns to be returned. Assume qp is the QueryParams object.Assume myLaye r //is a Layer object.
DoublePoint dblPt = new DoublePoint(-73.889444,42.765555);
double dRadius = 10.03;
try
{
fs = myLayer.searchWithinRadius(columnNames,dblPt,dRadius,e,qp);
}
catch(exception e)
{
e.printStackTrace();
}
==> searchWithinRegion
示例:
private boolean layerSearchWithinRegion()
{
//Assume fs is a FeatureSet object.Assume columnNames is a vector of the column s //to be returned.Assume qp is the QueryParams object.Assume myLayer is a Lay er //object.Assume vGeom is a VectorGeometry of TYPE_REGION
try
{
fs =myLayer.searchWithinRegion(columnNames,vGeom,qp);
}
catch(Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
==> searchWithinRectangle
示例:
//Assume fs is a FeatureSet object.Assume columnNames is a vector of the column s //to be returned.Assume qp is the QueryParams object.Assume myLayer is a Laye r //object.
DoubleRect dRect = new DoubleRect(-74.092662,42.765555,-73.668898,42.856420);
try
{
fs =myLayer.searchWithinRectangle(columnNames,dRect,qp);
}
catch(exception e)
{
e.printStackTrace();
}
==>searchAtPoint
示例:
//Assume fs is a FeatureSet object.Assume columnNames is a vector of the column s //to be returned.Assume qp is the QueryParams object.Assume myLayer is a Laye r //object.
DoublePoint dp = new DoublePoint(12.3456,-67.890);
{
fs = myLayer.searchAtPoint(columnNames,dp,qp);
}
catch(exception e)
{
e.printStackTrace();
}
==> searchByAttribute
示例:
//Assume fs is a FeatureSet object.Assume columnNames is a vector of the column s to //be returned.Assume qp is the QueryParams object.Assume myLayer is a Lay er //object.Assume attr is the attribute to search against.Assume colName is th e column to //search against.
try
{
fs =myLayer.searchByAttribute(columnNames,colName,attr,qp);
}
catch(Exception e)
{
e.printStackTrace();
return false;
}
==>searchByPrimaryKey
可以使用searchByPrimaryKey返回特定的FeatureSet。

private boolean layerSearchByPrimaryKey()
{
// Assume fs is a FeatureSet object. Assume columnNames is a vector of the //c olumns to be returned. Assume qp is the QueryParams object. Assume myLayer //i s a Layer object. Assume colName is the column to search against. Assume pk i s a //PrimaryKey from a previous search.
PrimaryKey[] arraypk = new PrimaryKey[1];
arraypk[0] = pk;
try
{
fs = myLayer.searchByPrimaryKey(columnNames,arraypk,qp);
}
catch(Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
}
专题四:怎样对空间特征值对象编辑
可以通过addFeature,addFeatureSet,replaceFeature,removeFeature对图层数据进行编辑,图层必须是An notation图层或通过JDBC表打开的图层。

需要编辑的图层必须使用LocalDataProviderRef。

可以可以使用F eatureFactory创建Feature或使用search方法获取FeatureSet。

1. 编辑Annotation图层
Annotationt图层的编辑只影响当前的MapJ,会改变地图图像的内容,与原始数据无关。

添加到Annotatin图层上的Feature必须有非空的PrimaryKey。

添加到Annotation图层上的Feature必须和添加到该图层上的第一个Feature有相同的PrimaryKey结构,即相同的Attribute类型和数量。

在使用FeatureFactory创建Feature的时候,应该使用MapJ的Numeric CoordSys。

2.编辑JDBC表图层
JDBC图层可以由数据库里的表定义或使用pass-througth查询定义。

只有通过表定义的图层才可以编辑,图层上的修改被保存在数据库内。

编辑图层时注意表结构,如字段是否非空,字段是否>0,字段长度等问题,同时必须有权限修改数据库的这个表。

MapXtreme Java使用单独的事务处理对象编辑请求,如果请求成功马上向数据库提交,否则rollback。

如果使用addFeatureSet,则需要对Features集合中的每一个Feature进行提交。

在添加Feature或替换Feature时注意分配PrimaryKey值。

下面是针对Oracle8i Spatial,IUS with S patialWare DataBlade和DB2 with Spatialware Extender的说明。

1)Oracle8i Spatial
可以使用自动分配或给定的值;
PrimaryKey的字段个数可以从1到n;
字段类型可以是整型或字符型;
添加Feature是必须给定PrimaryKey,替换时可选;
在更新Feature时如果给定了PrimaryKey,数据库将被更新,否则保持原值;
提供给Feature的PrimaryKey会正确地赋值给数据库中的相应字段;
使用addFeature时如果执行成功,将返回PrimaryKey。

2)IUS with SpatialWare DataBlade
IUS仅识别SW_MEMBER作为PrimaryKey;
PrimaryKey的字段个数可以从1到n;
字段类型只允许整型;
使用addFeature和replaceFeature时都不用指定PrimaryKey,即使指定了,也被忽略;
SW-MEMBER会自动取最大值加1,描述PrimaryKey的字段如果不是SW_MEMBER根本就不会被设置;
使用addFeature时不会返回PrimaryKey。

3)DB2 with Spatial Extender
PrimaryKey由Extender设置;
PrimaryKey的字段个数可以从1到n;
字段类型只允许整型;
使用addFeature和replaceFeature时都不用指定PrimaryKey,即使指定了,也被忽略;
如果没有指定PrimaryKey,就取Primary字段的最大值加一;
使用addFeature时如果执行成功,将返回PrimaryKey。

在向JDBC表图层添加Feature时,按照MapJ的Numeric 投影进行,MapXtreme可以进行相应的投影转换。

在创建图层时,在TableDescHelper中如果指定了保存Feature Rendition 或Label Rendition信息的字段,MapXtreme可以保存这些信息。

另外,MapXtreme只能将Rendtion保存在RenditionType.mapxtr eme格式中,而不是保存在RenditionType.mapbasic格式中,只能读。

添加Feature(addFeature)时,如果Rendition字段的类型是RenditionType.mapbasic,保存时该字段将是null。

若使用replaceFeature,上述字段将保留原值。

专题五:怎样进行专题分析
专题五:怎样进行专题分析
1 专题图概念
使用专题地图可以将图层数据颜色、样式等形式表现在地图上,从而可以看到数据的分布发展趋势,这些是传统的数据报表所不能完成的。

专题图示例如图:
MapXtreme Java支持如下几种专题图:
1)OverrideTheme:可以改变整个图层的显示
2)RangedTheme:按数据将地图分组调整显示
3)IndividualvalueTheme:按数据调整每个图元显示
4)SelectionTheme:控制选中图元的显示
对于RangedTheme和IndividualvalueTheme可以生成对应于专题图的图例,图例会随专题的变化而更新。

这两种专题可以通过AddTheme向导Bean创建。

和专题图相关有几个对象:
ThemeList:
通过Layer对象可以得到ThemeList,ThemeList是一个集合,有添加、删除、排序等功能。

一个图层可以有多个Theme专题,如果它们是同一效果的专题(如都是填充)则只有最上面的专题决定地图的显示,也就是ThemeList的最后一个。

另外,一个图层不同效果的专题可以叠加在一起显示,例如,一个专题以不同颜色填充表现数据,另一个以不同图案(如斜线)表示数据,则这两个专题都会在地图上显示。

Theme:可以得到专题表现的字段或专题的名字。

Rendition:可以控制专题的显示。

2 创建不同类型专题图
1 OverrideTheme
给一个Rendition就可以创建OverrideTheme,如:
// Assume myLayer is a Layer object.
// Assume myRend is a Rendition object.
OverrideTheme myOTheme = new OverrideTheme(myRend,"MyTheme");
myLayer.getThemeList.add(myOTheme);
2 SelectionTheme
如下示例,将按点搜索的图元用红色显示:
// Assume layer as a Layer object
Vector v = new Vector();
DoublePoint dp = new DoublePoint(x, y);
FeatureSet fs = null;
// Select a feature at the specified location
fs = layer.searchAtPoint(v, dp, null);
// Create a SelectionTheme
SelectionTheme selTheme = new SelectionTheme("PointSelection");
// Create a Selection object, and add the selected features
Selection sel = new Selection();
sel.add(fs);
// Assign the Selection object to the SelectionTheme
selTheme.setSelection(sel);
// Assign the display style of the SelectionTheme
Rendition rend =RenditionImpl.getDefaultRendition();
rend.setvalue(Rendition.FILL, Color.red);
selTheme.setRendition(rend);
// Add the SelectionTheme to the layer's list of themes
layer.getThemeList().add(selTheme)
3 RangedTheme
范围专题根据图层中数据的数值分成几个范围,然后将图元分为几组,每组有一个Rendition控制图元的显示。

MapXtreme提供了一系列的对象用来控制范围专题。

下面先介绍一个示例,然后介绍和范围专题相关的对象:
示例:
Layer lyr=null;
Rendition yellow=RenditionImpl.getDefaultRendition();
Rendition red=RenditionImpl.getDefaultRendition();
lyr = m_map.getLayers().getLayer("States.tab");
String colName = "Pop_1990";
ColumnStatistics colStats =lyr.f etchColumnStatistics(colName);
// Set number of breaks for data
int numBreaks=5;
// Compute the distribution of data with 5 breaks and
// Equal Ranges
Vector rBreaks = puteDistribution(numBreaks,colStats,Bucketer.DISTRIBUTION_TY PE_EQUAL_RANGES);
// Set up a red and a yellow rendition and then
// spread the colors
yellow.setvalue(Rendition.FILL, Color.yellow);
yellow.setvalue(Rendition.STROKE_WIDTH, 2);
red.setvalue(Rendition.FILL, Color.red);
red.setvalue(Rendition.STROKE_WIDTH, 4);
Vector rends = LinearRenditionSpreader.spread(numBreaks, yellow, red);
// Create Theme object
RangedTheme rTheme = new RangedTheme(colName, rBreaks, rends, "States by Pop_1990 ");
// Get ThemeList class object
ThemeList tList=lyr.getThemeList();
// Add theme to Layers themeList
tList.add(rTheme);
其中:
ColumnStatistics
通过fetchColumnStatistics可以取得ColumnStatistics对象,该对象可以在使用Bucketer对象创建范围分割点时会用到。

通过ColumnStatistics对象可以得到数据的最大、最小和中间值,或者标准差等。

Bucketer
该对象使用computeDistribution来计算范围间的分割点。

使用给方法时需要给出范围总数、ColumnStat istics对象和范围分布的类型。

范围分布的类型有以下几种:
1)DISTRIBUTION_TYPE_EQUAL_COUNT(等个数)
2)DISTRIBUTION_TYPE_EQUAL_RANGES(等范围)
3)DISTRIBUTION_TYPE_STANDARD_DEVIATION(标准差):以中间值为中心将范围上下作标准差分布。

RoundOff
给对象可以决定范围是从实际的字段数值靠着最小值还是最大值。

LinearRenditionSpreader
范围专题显示时,需要用不同的颜色,的渐变表示这一情况。

使用该对象的spread,给一个起始的Rendi tion、最后一个Rendition和范围数,中间每个范围的Rendition会自动计算,最后spread返回一个Ren dition Vector。

自定义RangedTheme示例
该示例自己定义Rendition,自己分割范围。

// Set up the ranges
Vector rBreaks = new Vector();
rBreaks.addElement(new Attribute(1));
rBreaks.addElement(new Attribute(5));
rBreaks.addElement(new Attribute(7));
// Set up the renditions
Vector rends= new Vector();
rends.addElement(redRendition);
rends.addElement(grayRendition);
rends.addElement(greenRendition);
// Create a ranged theme object
RangedTheme rTheme = new RangedTheme(themeCol, rBreaks,rends, "States by Pop_1994");
// Assign theme to layers as element 1
myMap.getLayers().elementAt(1).getThemeList().add(rTheme);
// Draw the map
// Create an ImageRequestComposer
ImageRequestComposer imageRC =ImageRequestComposer.create(myMap, 256, Color.blue,"image/ gif");
// Create a MapXtremeImageRenderer
MapXtremeImageRenderer renderer = new MapXtremeImageRenderer("http://localhost:8080// mapxtreme40/servelet/mapxtreme";);
// Render the map
Renderer.render(imageRC);
// Render the map to the file
Renderer.toFile("comp.gif");
4 IndividualvalueTheme
示例:
// get a reference to the layer we will be applying theme to
lyr = lyrs.add(dpr, ttdh, "Territories");
// create a new theme object
IndividualvalueTheme iValThm = new IndividualvalueTheme("CoverageTerritory", "Sales
Coverage Breakdown");
// create a rendition
Rendition rend=RenditionImpl.getDefaultRendition();
// assign color to rendition add attribute to theme with previously set renditio n
rend.setvalue(Rendition.FILL, Color.red);
iValThm.add(new Attribute("SouthWest"), rend);
// assign color to rendition add attribute to theme with previously set renditio n
rend.setvalue(Rendition.FILL, Color.blue);
iValThm.add(new Attribute("SouthEast"), rend);
// assign color to rendition add attribute to theme with previously set renditio n
rend.setvalue(Rendition.FILL, Color.green);
iValThm.add(new Attribute("Central"), rend);
// Add the theme to layers theme list
lyr.getThemeList().add(iValThm);
// Store column name and type in hashtable
Hashtable ht = new Hashtable();
ht.put("geomtype",IndividualvalueThemeLegend.REGION_GEOMETRY);
ht.put("lableorder",IndividualvalueThemeLegend.ORDER_ASCENDING);
// Create new legend passing theme and hashtable. The set Theme Title.
IndividualvalueThemeLegend iValThmLeg;
iValThmLeg = new IndividualvalueThemeLegend(iValThm, ht);
iValThmLeg.setTitle("Coverge Territory legend");
// Generate gif image from legend
iValThmLeg.toFile("c:\\temp\\terrLeg.gif", "image/gif");
3 图例
对于范围值和独立值专题图可以创建图例,并且可以修改图例的字体,标题等信息。

图例也可以输出为一个栅格图文件,使用Bean编程时也可以使用图例。

每个专题图都有图例对象,但只有范围值和独立值专题的图例对象不是空。

如果要图例和专题图关联起来,需要调用theme.setLegend。

示例:
// Create Theme object
// Assume rends as a Rendition object
// Assume colName as a attributeName(String)
// Assume rBreaks as a breakPoints Vector
RangedTheme rTheme = new RangedTheme(colName,rBreaks, rends, "States by Pop_1990");
// Create a default legend
RangedThemeLegend rThmLeg =rTheme.createDefaultLegend(null);
// OR, Create a theme legend instance using theme and setting hashtable
// Add theme settings to hashtable
Hashtable ht = new Hashtable();
ht.put("geomtype",RangedThemeLegend.REGION_GEOMETRY);
ht.put("lableorder",RangedThemeLegend.ORDER_ASCENDING);
RangedThemeLegend rThmLeg = new RangedThemeLegend(rTheme, ht);
// Set legend title
rThmLeg.setTitle("Ranged Theme legend");
// send legend to image file
rThmLeg.toFile("c:\\temp\\rangeLeg.gif", "image/gif");
如果使用LegendContainerBean可以将它放在VisualMapJ中,图例都会显示在Bean中,如果专题图改变,LegendContainerBean中的图例也会调整。

除了专题图图例外,图层中的图元也有一个图例CatographicLegend,可以使用com.mapi nfo.legend.CatographicLegend来创建。

下面是一个示例:
// Assume mapJ is already initialized
Layer landmarks = mapJ.getLayers().getLayer("landmarks");
// create the legend with title "State Landmarks"
CartographicLegend legend = new CartographicLegend("StateLandmarks");
// Perform a searchAll() on the layer to get its entire
// FeatureSet - need to make sure we fetch the column that
// we want to label with in the legend
Vector columns = new Vector();
columns.add("Name");
FeatureSet fs = landmarks.searchAll(columns, null);
// add the FeatureSet to the legend, and specify that we
// want to label each feature's rendition with the value in the "Name" column
legend.addFeatureSet(fs, "Name");
// always dispose of FeatureSet once you're done with it!
fs.dispose();
4 专题图向导Bean
通过专题向导可以给当前地图里的图层创建范围值或独立值专题,现在支持为数字、字符和日期型字段和点、线、面图层创建专题图,也可以创建一个默认的图例。

通过Bean还可以改变专题和图例的样式,范围划分等。

在同一个地图上的AddTheme Bean和VisualMapJ可以自动关联,如果没有自动关联,可以使用AddTheme Bean的setVisualMapJ(VisualMapJ)来指定。

下面是Bean的一个界面:
专题六:怎样进行数据绑定---将数据库中的属性数据与地图进行动态连结
MapXtreme for Java支持数据绑定,可以将和地图相关的数据信息保存在数据库中,通过数据绑定将数据库内的数据在地图上可视化。

数据绑定需要使用DataProvider:com.mapinfo.dp.databinding。

数据绑定的步骤:
1为每个表创建TableDescHelper
2创建DataBindingTableDescHelper,需要第一步中创建的TableDescHelper为参数,还需要关联两个表的字段(未必同名)。

3为每个表创建DataProviderHelper
4创建DataBindingDataProviderHelper,需要用到上一步的DataProvider
5使用DataBindingDataProviderHelper创建DataProviderRef
6向Layers中添加Layer
另外,也可以通过图层控制Bean将数据绑定的图层添加到VisualMapJ。

数据绑定示例:
TABDataProviderHelper tabDPH = new TABDataProviderHelper(directory);
JDBCDataProviderHelper jdbcDPH = new JDBCDataProviderHelper("jdbc:oracle:thin:@localhost: 1521:sid", user, pass,"oracle.jdbc.driver.OracleDriver");
DataBindingDataProviderHelper dbDPH = new DataBindingDataProviderHelper(tabDPH, jdbcDP H);
String tabCols = {"State"};
String jdbcCols = {"STATEABBREVIATION"};
TABTableDescHelper tabDesc = new TABTableDescHelper("states.tab");
JDBCTableDescHelper jdbcDesc = new JDBCTableDescHelper("STATES", null, false);
DataBindingTableDescHelper dbDesc = new DataBindingTableDescHelper(tabDesc, jdbcDes
c, tabCols,jdbcCols);
DataProviderRef dpRef = new MapXtremeDataProviderRef(dbDPH, mapXtremeURL);
Layer lyr = mapj.getLayers().add(dpRef, dbDesc,"DataBinding");
下面介绍数据聚合的概念:(com.mapinfo.dp.databinding.Aggregation)
这个类决定数据绑定时,如果处理相关的多条记录。

如:
dbDesc.addAggregation(Aggregation.SUM);
数据聚合有如下几种类型:
1)sum求和
2)count求个数
3)average求平均
4)minimum求最小值
5)maximum求最大值
可以为每个字段定义聚合,但各个字段必须相同。

聚合的所有操作都属于DataBindingTableDescHelper.
专题七:怎样实现GPS监控
MapXtreme的新版本中提供了一个新的CompositeRender。

通过它可以仅仅将某些需要改变的图层重画刷新,这样MapXtreme可以将图层分为静态图层和动态图层,前者只画一次并保存为本地的栅格图,而每一个处理输出地图请求时只重画动态图层。

这样就可以实现诸如地理编码、车辆监控之类的应用。

如:
地理编码:
创建一个临时图层(Annotaion)用来保存地理编码的点符号,通过CompositeRender可以在生成绘出地图后再画点符号,符号在地图(包括地图标注)的上面。

如果不使用CompositeRender,标注总是最后绘制,因此显示的编码点符号会位于标注的下面。

车辆监控:
象GPS监控之类的应用,可以将地图绘制一次,每次GPS数据更新时,只重画车辆的位置。

使用CompositeRender的注意事项:
•静态图层会保存在本地,需要占用内存,如640 x 480的图像需要至少2.7 MB;
•改变视野时,静态图层可能变形,如线出现锯齿;
•改变地图中心时,静态图层的边缘不能完成平移,这时必须重新生成静态图层。

示例:
下面代码演示了如何在地图上显示移动目标:
try {
// ASSUMPTIONS:
// The variable mapj is of type MapJ and has loaded a map
// The variable req is of type HttpServletRequest
// The variable res is of type HttpServletResponse
// The variable dp is of type DoublePoint
// Add annotation layer - this layer will consist of one image symbol to "anim ate"
AnnotationTableDescHelper atdh = new AnnotationTableDescHelper("Animation_Layer");
AnnotationDataProviderHelper adph = new AnnotationDataProviderHelper();
LocalDataProviderRef ldpr = new LocalDataProviderRef(adph);
//Add the annotation layer
Layer animate_layer = mapj.getLayers().insert(ldpr, atdh,0, "Animation_Layer");
//Create the rendition for the point
Rendition r = RenditionImpl.getDefaultRendition();
r.setvalue(Rendition.SYMBOL_MODE,Rendition.SymbolMode.IMAGE);
r.setvalue(Rendition.SYMBOL_URL, "file:///C:/images/car.gif");
//Create the point
FeatureFactory ff = mapj.getFeatureFactory();
//An array containing a single int Attribute
Attribute[] aAIntAttribute = {new Attribute(33)};
//create a new Primary Key an an integer
PrimaryKey pkey = new PrimaryKey(aAIntAttribute);
Feature f = ff.createPoint(dp, r, aAIntAttribute, pkey);
PrimaryKey pk = animate_layer.addFeature(f);
// Create the ImageRequestComposer
ImageRequestComposer imageRC =ImageRequestComposer.create(mapj, 256, Color.blue,"image/g if");
/*
Create the composite renderer
Render the image
Stream the image back to the client
*/
CompositeRenderer compositeRenderer = new CompositeRenderer("http://localhost:8080/ma pxtreme40/servlet/mapxtreme";, 0);
compositeRenderer.render(imageRC);
ServletOutputStream sos = res.getOutputStream();
compositeRenderer.toStream(sos);
//Set this attribute to false so that the bottom image is not rendered next ti me
compositeRenderer.setRedrawBottom(false);
} catch(Exception e) {
//Take appropriate error handling steps
}
专题八:怎样调用空间数据库中的地图
在地图中添加空间地图图层首先要定义Layer。

1. 如何定义Layer(使用DataProvider)
定义Layer的关键是Data Provider。

Layer对象有一个内部的对象叫做Data Provider,它不是直接由用户创建的,但是它的描述确实定义一个图层。

要描述Data Provider通过如下接口:
•TableDescHelper –描述数据
•DataProviderHelper –定义数据的源
•DataProviderRef –描述获取数据的方式
MapXtreme提供一系列DataProvider,可以读取如下类型的数据:
•MapInfo tab format (.tab)
•Oracle8i with Spatial Option
•Informix Universal Server SpatialWare DataBlade
•DB2 SpatialWare Extender
•JDBC compatible tables containing longitude and latitude columns
•GeoTIFF and MIGrid Raster
•ESRI Shapefiles
•Data Binding :可以将两种数据源的数据绑定在一起,在一个图层显示信息
•Annotation :信息不是实际的数据表,信息存在内存中
MapXtreme读取不同数据的示意图:
下面介绍如何描述DataProvider:
n TableDescHelpers
TableDescHelpers描述要读取哪些数据,对于不同数据源有相应的TableDescHelpers,TableDescHelper s用几个参数描述数据。

如:访问MapInfo Table 需要使用TABTableDescHelper,需要table 名字参数。

对于Oracle8i数据需要使用OraSoTableDescHelper ,需要表名或SQL语句参数。

后面的相关部分有示例代码。

n DataProviderHelpers
DataProviderHelpers定义数据源。

对于MapInfo Table来说,使用TABDataProviderHelper描述Table 的数据源,源就是.tab文件所在的目录。

Oracle8i的数据使用OraSoDataProviderHelper描述数据源,需要主机名、用户名、密码等。

n DataProviderRef
有两种方式获取数据:一种是直接方式,如MapJ通过JDBC连接数据库取得数据,需要使用LocalDataPro viderRef;另一种是间接方式,通过MapXtremeServlet获取数据,需要使用MapXtremeDataProviderRef。

直接方式示意:
间接方式示意:
在这个示意图中MapJ处于客户端(Client),有一个名为stub的DataProvider,真正描述数据的Data Provider由MapXtremeServlet创建。

所有访问数据的组件可以放在中间层MapXtremeServlet处,这样客户端就不必都安装JDBC驱动。

这是一个典型的三次应用:应用,数据处理逻辑,数据存储。

注意:何时读取数据?
定义获创建Layer后,并不立即读取数据。

只有有数据请求时,才真正到数据源读取数据,如:使用Laye r的getTableInfo,使用search或响应render请求。

2. 添加Layer
添加图层分几步:
创建TableDescHelpers
创建DataProviderHelpers
创建DataProviderRef
使用Layers.add添加图层到最后一层或使用Layers.insert插入到某一个位置
下表总结了连接不同数据源时使用的DataProviderHelpers和TableDescHelper:
Data Source
TableDescHelper
DataProvider
MapInfo Tables
TABTableDescHelper
TABDataProviderHelper
Oracle8i with Spatial Option
OraSoTableDescHelper
OraSoDataProviderHelper
Informix Universal Server SpatialWare DataBlade
IusSpwTableDescHelper
IusSpwDataProviderHelper
DB2 SpatialWare Extender
Db2SpwTableDescHelper
Db2SpwDataProviderHelper
JDBC compatible tables containing longitude and latitude columns XYTableDescHelper
XYDataProviderHelper
Annotation Layers
AnnotationTableDescHelper
AnnotationDataProviderHelper
GeoTIFF Raster
GeoTIFFTableDescHelper
GeoTIFFDataProviderHelper
ESRI Shapefiles
ShapeTableDescHelper
ShapeDataProviderHelper
Data Binding 1
DataBindingTableDescHelper
DataBindingDataProviderHelper
ImageIO *
ImageIOTableDescHelper
ImageIODataProviderHelper
* 需要JDK1.4
下面是添加Oracle8i图层的示例。

Oracle8i Data Provider示例:
// specify the url to the MapXtreme servlet which remotely connects us to th
e map //engine
String mapXtremeURL = "http://localhost:8080/mapxtreme40/servlet/mapxtreme";;
// Create the Remote Dataprovider needed to access the Data
// Using pooled connections (Recommended) CommonDataProviderHelpers
// Using Database specific DataProviderHelper
OraSoDataProviderHelper oraSoDPHelper=new OraSoDataProviderHelper("databasename",1000, "D Bsid","tester", "tester", DriverType.thin);
// Create a String array with the name(s) of the column(s) to
use as a unique key for records in the TableName
String[] idColumn = {"S_MEMBER"};
// Now create a Table Desc helper
// This code uses the Constructor required when using a tablename
OraSoTableDescHelper oraSoTDHelper = new OraSoTableDescHelper("STATES", false, idColum n,"S_GEOMETRY", null,RenditionType.none, null,RenditionType.none, CoordSys.longLatWGS8 4, 2,"TESTER");
// This code uses the Constructor required when using a QueryOraSoTableDescHelpe
r oraSoTDHelper = new OraSoTableDescHelper("Select S_MEMBER, S_GEOMETRY,
POP_1990 From STATES Where STATE = 'NY'", idColumn,"S_GEOMETRY", null,RenditionType. none, null,RenditionType.none ,CoordSys.longLatWGS84, 2);
// Create the Remote Dataprovider needed to access the Data
MapXtremeDataProviderRef mxtDPRef = new MapXtremeDataProviderRef(oraSoDPHelper, mapXtre meURL);
//assign it to MapJ - note getLayers()
m_myMap.getLayers().add(mxtDPRef, oraSoTDHelper, "OraSoLayer");
专题九:怎样快速响应多并发用户远程数据库数据请求
1 连接缓冲池
MapXtreme使用连接缓冲池,可以创建一组数据库的连接,这些连接可以被有效的重用,这要就不必费时费力为每个客户端的请求创建一个连接。

那么,MapXtreme中的连接缓冲池是如何工作的呢?不论是MapXtremeServlet还是MapJ使用连接缓冲池的方式都是一样的,JDBC从RDBMS取数据时都首先从连接缓冲池中查找连接,如果找到了一个可用的连接就直接用,否则创建一个新的连接。

连接使用后再放回连接缓冲池。

如果此时连接缓冲池已满,则关掉连接并释放资源。

对于MapXtremeServlet使用连接缓冲池的情况,如果在classpath中找到了miconnections.properties 文件,就会使用连接缓冲池。

该文件描述的连接在MapXtreme初始化时会被预启动,MapXtremeServlet实例销毁时连接自动关闭。

对于MapJ的应用,如果在Classpath中能找到miconnections.properties文件也会自动自动预先产生一个连接缓冲池。

这种情况只能创建一个连接缓冲池,该连接缓冲池被应用中的各个MapJ使用。

MapXtreme 需要从远程数据库取数据,如执行查询,获取图层上的数据,数据地图等等,如果连接缓冲池存在,这个过程就会使用连接缓冲池。

另外,MapJ也可以使用MIConnectionPoolManager在运行时创建另外一个连接缓冲池。

程序退出,调用MIConnectionPoolManager的dispose方法可以关闭连接。

2 配置JDBC 连接。

相关文档
最新文档