查詢ArcIMS中的動態圖層(引自ESRI北京論壇)
為了解決客戶的問題, 搗鼓了一下arcims的動態圖層,因為前后花了我十來個小時,所以還是想寫下來和大家分享,有不同意見歡迎廣泛交流.
一.關于添加動態圖層
這是個很不值得一提的問題,看到這個標題,估計很多老師和資深人士都想扔磚頭過來.大家還是耐心點兒,古典長篇名著還要從滾滾長江東逝水開始呢.我們也先弄個引子,順便充實一下篇幅.
1.修改AXL文件
添加動態圖層有個前提,就是必須在AXL中,為MAP元素,添加dynamic屬性,即:
<MAP dynamic="true">
這個步驟在Author中無法完成,只能通過文本編輯器手工編輯了.建議使用EmEditor或者VS.
2.動態添加
通過發送ArcXML或者調用連接器中封裝的對象,我們就可以動態添加指定的圖層,下面是使用ArcIMS Java Connector的例子:
(1)動態添加SHAPE圖層
.....
ShapeWorkspace shpw = new ShapeWorkspace();
shpw.setDirectory("D:\\WorkSpace\\sd");
shpw.setName("sde_ws-1");
map.addWorkspace(shpw);
Dataset data = new Dataset();
data.setName("地區邊界");
data.setWorkspaceName(shpw.getName());
data.setType("polygon");
FeatureLayer fl = new FeatureLayer("2", null, null);
fl.setDataset(data);
fl.setName("地區邊界");
fl.setVisible(true);
SimpleRenderer sr = new SimpleRenderer();
SimplePolygonSymbol sm=new SimplePolygonSymbol();
sm.setFillColor("255,0,0");
sm.setBoundaryColor("0,0,255");
sm.setFillType(SimplePolygonSymbol.SOLID);
sr.setSymbol(sm);
fl.setRenderer(sr);
map.getLayers().add(fl);
(2)SDE圖層
......
SDEWorkspace sdeWSP = new SDEWorkspace();
sdeWSP.setName("sde_ws-4");
sdeWSP.setInstance("port:5151");
sdeWSP.setServer("jerry");
sdeWSP.setPassword("sde");
sdeWSP.setUser("sde");
map.addWorkspace(sdeWSP);
Dataset data = new Dataset();
data.setName("SDE.地區邊界");
data.setWorkspaceName(sdeWSP.getName());
data.setType("polygon");
FeatureLayer fl = new FeatureLayer("2", null, null);
fl.setDataset(data);
fl.setName("地區邊界");
fl.setVisible(true);
SimpleRenderer sr = new SimpleRenderer();
SimplePolygonSymbol sm=new SimplePolygonSymbol();
sm.setFillColor("255,0,0");
sm.setBoundaryColor("0,0,255");
sm.setFillType(SimplePolygonSymbol.SOLID);
sr.setSymbol(sm);
fl.setRenderer(sr);
map.getLayers().add(fl);
二.動態圖層的查詢
1.還是從修改AXL文件開始
如果要使添加的動態圖層可以被查詢,比如Identify, 緩沖區查詢等等,必須具備一個前提,必須在AXL中,為MAP元素,添加dynamicfeature="true">屬性,即:
<MAP dynamic="true" dynamicfeature="true">
2.兩個注意事項
經過反復測試,發現必須注意兩點:
(1)執行查詢時,必須添加對于LAYER的DATASET的定義.而且,DATASET的workspace屬性必須是已經包含在AXL文件中.
(2)如果不是直接發送ArcXML,那么查詢之前需要Remove掉動態添加上去的所有workspace
3.執行查詢的例子
查詢的應用類型很多,包括點擊地圖的Identify,還有圖上的框選,圈選,多邊形選擇,甚至緩沖區查詢等等. 有時候還需要結合屬性where條件的篩選.對于ArcIMS而言,都是
SPATIALQUERY. 下面就以Identify的點擊查詢為例.
(1)直接發送ArcXML:
<?xml version="1.0" encoding="UTF-8"?><ARCXML version="1.1">
<ARCXML>
<REQUEST>
<GET_FEATURES envelope="true" geometry="true" outputmode="newxml">
<LAYER id="2" type="featureclass">
<DATASET name="SDE.地區邊界" type="polygon" workspace="sde_ws-4" />
</LAYER>
<SPATIALQUERY searchorder="optimize" subfields="DIST_CODE NAME #SHAPE#">
<SPATIALFILTER relation="area_intersection">
<ENVELOPE maxx="120.9610390189751" maxy="37.32400679575094" minx="120.9608390189751" miny="37.32380679575093"/>
</SPATIALFILTER>
</SPATIALQUERY>
</GET_FEATURES>
</REQUEST>
</ARCXML>
注意在LAYER的元素中添加的DATASET的定義.其中,DATASET的workspace屬性必須是已經包含在AXL文件的WORKSPACE中.什么
意思呢?就拿這個例子中而言,其中的"sde_ws-4"必須是在這個地圖服務的AXL文件中定義過的SDEWORKSPACE.
(2)使用Java Connector程序進行查詢:
......
//注意在這里需要獲取當前map中的workspace,賦給一個臨時變量,然后從map中去除
SDEWorkspace sdeWSP = new SDEWorkspace();
sdeWSP=(SDEWorkspace)map.getWorkspace(0);
map.removeWorkspace(0);
FeatureLayer fLayer=(FeatureLayer)map.getLayers().item(0);
//注意在這里必須聲明Dataset,并且賦予相應的Name, workspace,type等屬性,其中workspace名稱很重要,必須也是定義在AXL中.
//然后把Dataset對象賦給FeatureLayer對象
Dataset data = new Dataset();
data.setName("SDE.地區邊界");
data.setWorkspaceName("sde_ws-4");
data.setType("polygon");
fLayer.setDataset(data);
com.esri.aims.mtier.model.map.layer.query.Filter filter= new com.esri.aims.mtier.model.map.layer.query.Filter();
Point pnt = map.toMapPoint(Double.parseDouble(x), Double.parseDouble(y));
double maxx = pnt.getX() + 0.0001;
double maxy = pnt.getY() + 0.0001;
double minx = pnt.getX() - 0.0001;
double miny = pnt.getY() - 0.0001;
Envelope envelope = new Envelope();
envelope.setMinX(minx);
envelope.setMinY(miny);
envelope.setMaxX(maxx);
envelope.setMaxY(maxy);
filter.setSpatialShape(envelope);
filter.setGlobalEnvelope(true);
filter.setBoundingEnvelope(true);
filter.addSubField("DIST_CODE");
filter.addSubField("NAME");
filter.setRelation(com.esri.aims.mtier.model.map.layer.query.Filter.AREA_INTERSECTION);
fLayer.getRecordset().clearRecordset();
fLayer.setFilterObject(filter);
map.refresh();
//執行完查詢之后,如果有必要,將之前去除的workspace添加到map中.
map.addWorkspace(sdeWSP);
......
4.常見錯誤信息
(1) Underlying input stream returned zero bytes
表明沒有指定Layer的Dataset,或者Dataset中的workspace沒有定義在AXL文件中.
對于僅僅添加動態圖層而言,workspace的名字可以是任意的,而且可以不用定義在AXL文件中.但是如果涉及到對于動態圖層的查詢,就必須注意這一點.
(2) map.refresh()時候,提交到后臺的請求是GET_IMAGE而不是想要執行的GET_FEATURE
這個問題的原因是因為沒有在查詢之前去除map中包含的workspace
(3) 添加了動態圖層以后,無法查詢其他固有的圖層
這個問題的原因同2,也是因為沒有在查詢之前去除map中包含的workspace.
這是個很奇怪的問題,畢竟沒有涉及到對動態圖層的查詢,但是其他圖層顯然受到了動態圖層的影響, anyway, 這樣做了以后就OK了.
一.關于添加動態圖層
這是個很不值得一提的問題,看到這個標題,估計很多老師和資深人士都想扔磚頭過來.大家還是耐心點兒,古典長篇名著還要從滾滾長江東逝水開始呢.我們也先弄個引子,順便充實一下篇幅.
1.修改AXL文件
添加動態圖層有個前提,就是必須在AXL中,為MAP元素,添加dynamic屬性,即:
<MAP dynamic="true">
這個步驟在Author中無法完成,只能通過文本編輯器手工編輯了.建議使用EmEditor或者VS.
2.動態添加
通過發送ArcXML或者調用連接器中封裝的對象,我們就可以動態添加指定的圖層,下面是使用ArcIMS Java Connector的例子:
(1)動態添加SHAPE圖層
.....
ShapeWorkspace shpw = new ShapeWorkspace();
shpw.setDirectory("D:\\WorkSpace\\sd");
shpw.setName("sde_ws-1");
map.addWorkspace(shpw);
Dataset data = new Dataset();
data.setName("地區邊界");
data.setWorkspaceName(shpw.getName());
data.setType("polygon");
FeatureLayer fl = new FeatureLayer("2", null, null);
fl.setDataset(data);
fl.setName("地區邊界");
fl.setVisible(true);
SimpleRenderer sr = new SimpleRenderer();
SimplePolygonSymbol sm=new SimplePolygonSymbol();
sm.setFillColor("255,0,0");
sm.setBoundaryColor("0,0,255");
sm.setFillType(SimplePolygonSymbol.SOLID);
sr.setSymbol(sm);
fl.setRenderer(sr);
map.getLayers().add(fl);
(2)SDE圖層
......
SDEWorkspace sdeWSP = new SDEWorkspace();
sdeWSP.setName("sde_ws-4");
sdeWSP.setInstance("port:5151");
sdeWSP.setServer("jerry");
sdeWSP.setPassword("sde");
sdeWSP.setUser("sde");
map.addWorkspace(sdeWSP);
Dataset data = new Dataset();
data.setName("SDE.地區邊界");
data.setWorkspaceName(sdeWSP.getName());
data.setType("polygon");
FeatureLayer fl = new FeatureLayer("2", null, null);
fl.setDataset(data);
fl.setName("地區邊界");
fl.setVisible(true);
SimpleRenderer sr = new SimpleRenderer();
SimplePolygonSymbol sm=new SimplePolygonSymbol();
sm.setFillColor("255,0,0");
sm.setBoundaryColor("0,0,255");
sm.setFillType(SimplePolygonSymbol.SOLID);
sr.setSymbol(sm);
fl.setRenderer(sr);
map.getLayers().add(fl);
二.動態圖層的查詢
1.還是從修改AXL文件開始
如果要使添加的動態圖層可以被查詢,比如Identify, 緩沖區查詢等等,必須具備一個前提,必須在AXL中,為MAP元素,添加dynamicfeature="true">屬性,即:
<MAP dynamic="true" dynamicfeature="true">
2.兩個注意事項
經過反復測試,發現必須注意兩點:
(1)執行查詢時,必須添加對于LAYER的DATASET的定義.而且,DATASET的workspace屬性必須是已經包含在AXL文件中.
(2)如果不是直接發送ArcXML,那么查詢之前需要Remove掉動態添加上去的所有workspace
3.執行查詢的例子
查詢的應用類型很多,包括點擊地圖的Identify,還有圖上的框選,圈選,多邊形選擇,甚至緩沖區查詢等等. 有時候還需要結合屬性where條件的篩選.對于ArcIMS而言,都是
SPATIALQUERY. 下面就以Identify的點擊查詢為例.
(1)直接發送ArcXML:
<?xml version="1.0" encoding="UTF-8"?><ARCXML version="1.1">
<ARCXML>
<REQUEST>
<GET_FEATURES envelope="true" geometry="true" outputmode="newxml">
<LAYER id="2" type="featureclass">
<DATASET name="SDE.地區邊界" type="polygon" workspace="sde_ws-4" />
</LAYER>
<SPATIALQUERY searchorder="optimize" subfields="DIST_CODE NAME #SHAPE#">
<SPATIALFILTER relation="area_intersection">
<ENVELOPE maxx="120.9610390189751" maxy="37.32400679575094" minx="120.9608390189751" miny="37.32380679575093"/>
</SPATIALFILTER>
</SPATIALQUERY>
</GET_FEATURES>
</REQUEST>
</ARCXML>
注意在LAYER的元素中添加的DATASET的定義.其中,DATASET的workspace屬性必須是已經包含在AXL文件的WORKSPACE中.什么
意思呢?就拿這個例子中而言,其中的"sde_ws-4"必須是在這個地圖服務的AXL文件中定義過的SDEWORKSPACE.
(2)使用Java Connector程序進行查詢:
......
//注意在這里需要獲取當前map中的workspace,賦給一個臨時變量,然后從map中去除
SDEWorkspace sdeWSP = new SDEWorkspace();
sdeWSP=(SDEWorkspace)map.getWorkspace(0);
map.removeWorkspace(0);
FeatureLayer fLayer=(FeatureLayer)map.getLayers().item(0);
//注意在這里必須聲明Dataset,并且賦予相應的Name, workspace,type等屬性,其中workspace名稱很重要,必須也是定義在AXL中.
//然后把Dataset對象賦給FeatureLayer對象
Dataset data = new Dataset();
data.setName("SDE.地區邊界");
data.setWorkspaceName("sde_ws-4");
data.setType("polygon");
fLayer.setDataset(data);
com.esri.aims.mtier.model.map.layer.query.Filter filter= new com.esri.aims.mtier.model.map.layer.query.Filter();
Point pnt = map.toMapPoint(Double.parseDouble(x), Double.parseDouble(y));
double maxx = pnt.getX() + 0.0001;
double maxy = pnt.getY() + 0.0001;
double minx = pnt.getX() - 0.0001;
double miny = pnt.getY() - 0.0001;
Envelope envelope = new Envelope();
envelope.setMinX(minx);
envelope.setMinY(miny);
envelope.setMaxX(maxx);
envelope.setMaxY(maxy);
filter.setSpatialShape(envelope);
filter.setGlobalEnvelope(true);
filter.setBoundingEnvelope(true);
filter.addSubField("DIST_CODE");
filter.addSubField("NAME");
filter.setRelation(com.esri.aims.mtier.model.map.layer.query.Filter.AREA_INTERSECTION);
fLayer.getRecordset().clearRecordset();
fLayer.setFilterObject(filter);
map.refresh();
//執行完查詢之后,如果有必要,將之前去除的workspace添加到map中.
map.addWorkspace(sdeWSP);
......
4.常見錯誤信息
(1) Underlying input stream returned zero bytes
表明沒有指定Layer的Dataset,或者Dataset中的workspace沒有定義在AXL文件中.
對于僅僅添加動態圖層而言,workspace的名字可以是任意的,而且可以不用定義在AXL文件中.但是如果涉及到對于動態圖層的查詢,就必須注意這一點.
(2) map.refresh()時候,提交到后臺的請求是GET_IMAGE而不是想要執行的GET_FEATURE
這個問題的原因是因為沒有在查詢之前去除map中包含的workspace
(3) 添加了動態圖層以后,無法查詢其他固有的圖層
這個問題的原因同2,也是因為沒有在查詢之前去除map中包含的workspace.
這是個很奇怪的問題,畢竟沒有涉及到對動態圖層的查詢,但是其他圖層顯然受到了動態圖層的影響, anyway, 這樣做了以后就OK了.