发表用户:LongRiver
收集整理:James.Liu
相关讨论:http://www.mygis.com.cn/forum/dispbbs.asp?BoardID=11&id=3696
信息原始来源:不祥

文章标题:MapXtreme for Java开发专题五:怎样进行专题分析

专题五:怎样进行专题分析
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.fetchColumnStatistics(colName);

// Set number of breaks for data

int numBreaks=5;

// Compute the distribution of data with 5 breaks and

// Equal Ranges

Vector rBreaks = Bucketer.computeDistribution(numBreaks,colStats,Bucketer.DISTRIBUTION_TYPE_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来计算范围间的分割点。使用给方法时需要给出范围总数、ColumnStatistics对象和范围分布的类型。

范围分布的类型有以下几种:

1)  DISTRIBUTION_TYPE_EQUAL_COUNT(等个数)

2)  DISTRIBUTION_TYPE_EQUAL_RANGES(等范围)

3)  DISTRIBUTION_TYPE_STANDARD_DEVIATION(标准差):以中间值为中心将范围上下作标准差分布。

RoundOff

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

LinearRenditionSpreader

范围专题显示时,需要用不同的颜色,的渐变表示这一情况。使用该对象的spread,给一个起始的Rendition、最后一个Rendition和范围数,中间每个范围的Rendition会自动计算,最后spread返回一个Rendition 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 rendition

rend.setvalue(Rendition.FILL, Color.red);

iValThm.add(new Attribute("SouthWest"), rend);

// assign color to rendition add attribute to theme with previously set rendition

rend.setvalue(Rendition.FILL, Color.blue);

iValThm.add(new Attribute("SouthEast"), rend);

// assign color to rendition add attribute to theme with previously set rendition

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.mapinfo.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的一个界面: