SharpMap学习(2)
在經過第一篇的簡單學習之后,我們開始了解一些稍微有點兒意思的東西,進一步掌握和學習利用sharpmap進行開發的技巧。
這次,我們主要是跟大家一起學習一下如何根據地圖上的一個點,來查詢這個點所在的對象的信息,并顯示到點擊的位置。這非常有用,比如說一個想把一個房子顯示在地圖上,我們用鼠標一點,便知道這個房子里住的什么人,干什么的,以及其它相關信息。
同樣的,我們還是使用sharpmap提供的ajax控件,環境和第一篇一模一樣。但是這里,我們要引用一個叫做NetTopologySuite的類庫。它經常和SharpMap一起使用,這次我們只使用其中的一個小部分,廢話不多說,開始做。
這里我們使用asp.net ajax 1.0,首先引用了dll,并且拖上scripmanager并設置為EnablePageMethods=true,這樣我們就可以在頁面中寫靜態方法來實現AJAX。
在MapClicked方法(AjaxMapControl控件提供的方法,直接寫在js中即可,表示單擊的時候發生一些事情)中,我們調用我們寫的js,根據兩個點來返回一個字符串。這個字符串就是拼好的html,直接顯示出來。
Codefunction?MapClicked(event,obj)
????{
????????var?mousePos?=?SharpMap_GetRelativePosition(event.clientX,event.clientY,obj.container);
????????var?pnt?=?SharpMap_PixelToMap(mousePos.x,mousePos.y,obj);
????????var?field?=?document.getElementById('dataContents');
????????//field.innerHTML?=?"You?clicked?map?at:?"?+?pnt.x?+?","?+?pnt.y;
????????GetData(pnt.x,?pnt.y);
????}
?
這個方法里面的SharpMap_GetRelatiovePosition和?SharpMap_PixelToMap方法根據鼠標在屏幕上的坐標計算出鼠標點在地圖上的坐標,再調用我們自己寫的GetData方法即可。在GetData方法中,我們使用了PageMethods來調用一個后臺方法,并返回一個字符串。
?PageMethods.GetData(x, y, GetDataSuccess);
然后,在GetDataSuccess中調用一個寫好的用來顯示這些返回數據的方法(此方法來自網絡,js源碼如下)。
?
?
?
?
?
Code<script?type="text/javascript">
<!--
????var?ns4?=?document.layers;
????var?ns6?=?document.getElementById?&&?!document.all;
????var?ie4?=?document.all;
????offsetX?=?0;
????offsetY?=?20;
????var?toolTipSTYLE?=?"";
????function?initToolTips()?{
????????if?(ns4?||?ns6?||?ie4)?{
????????????if?(ns4)?toolTipSTYLE?=?document.toolTipLayer;
????????????else?if?(ns6)?toolTipSTYLE?=?document.getElementById("toolTipLayer").style;
????????????else?if?(ie4)?toolTipSTYLE?=?document.all.toolTipLayer.style;
????????????if?(ns4)?document.captureEvents(Event.MOUSEMOVE);
????????????else?{
????????????????toolTipSTYLE.visibility?=?"visible";
????????????????toolTipSTYLE.display?=?"none";
????????????}
????????????document.onclick?=?moveToMouseLoc;
????????}
????}
????function?toolTip(msg,?fg,?bg)?{
????????if?(toolTip.arguments.length?<?1)?//?hide
????????{
????????????if?(ns4)?toolTipSTYLE.visibility?=?"hidden";
????????????else?toolTipSTYLE.display?=?"none";
????????}
????????else?//?show
????????{
????????????if?(!fg)?fg?=?"#777777";?//fore?color
????????????if?(!bg)?bg?=?"#FFFFFF";?//bg?color
????????????var?content?=?msg;
????????????if?(ns4)?{
????????????????toolTipSTYLE.document.write(content);
????????????????toolTipSTYLE.document.close();
????????????????toolTipSTYLE.visibility?=?"visible";
????????????}
????????????if?(ns6)?{
????????????????document.getElementById("toolTipLayer").innerHTML?=?content;
????????????????toolTipSTYLE.display?=?'block'
????????????}
????????????if?(ie4)?{
????????????????document.all("toolTipLayer").innerHTML?=?content;
????????????????toolTipSTYLE.display?=?'block'
????????????}
????????}
????}
????function?moveToMouseLoc(e)?{
????????if?(ns4?||?ns6)?{
????????????x?=?e.pageX;
????????????y?=?e.pageY;
????????}
????????else?{
????????????x?=?event.x?+?document.body.scrollLeft;
????????????y?=?event.y?+?document.body.scrollTop;
????????}
????????toolTipSTYLE.left?=?x?+?offsetX;
????????toolTipSTYLE.top?=?y?+?offsetY;
????????return?true;
????}
????//-->
????</script>
?需要指出的是,這個效果需要做一些初始化的工作:
?? <div id="toolTipLayer" style="position:absolute;visibility: hidden;z-index:10000">??? </div>
??? <script type="text/javascript">
??????? initToolTips();
??? </script>
這樣,我們在前臺的工作就基本完成了。
當然,如果想要更好看一些,再寫一個css幫助從后臺傳來的html進行淡化。
?.clarity
??????? {
??????????? background-color:#4d7d99;
??????????? filter:alpha(opacity=80,Style=0);
????????}
OK,現在轉去后臺。
在根據兩個點查詢對象數據時,我們首先要初始化需要初始化shapefile,也就是你要查詢的那個層的數據源。
new SharpMap.Data.Providers.ShapeFile(filepath true);
然后遍歷shapefile里面的每一個feature,對比傳入的點和feature所在的Geometry,如果傳入的點在feature所在Geometry之內(within方法)的話,就讀取當前feature的一個attribute(通常是某個業務對象的ID),這樣,根據這個ID就能取到業務對象的值,然后Build一下HTML,返回就OK了。主要代碼如下:
Code???public?string?GetInfo(double?x,?double?y)
????????{
????????????SharpMap.Data.Providers.ShapeFile?oShape=(SharpMap.Data.Providers.ShapeFile)GetShapeFile(filepath);
????????????if?(!oShape.IsOpen)
????????????{
????????????????oShape.Open();
????????????}
????????????uint?iFeature?=?(uint)oShape.GetFeatureCount();
????????????SharpMap.Geometries.Point?oPoint?=?new?SharpMap.Geometries.Point(x,?y);
????????????GisSharpBlog.NetTopologySuite.Geometries.Geometry?oPt?=?SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(oPoint,?new?GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory());
????????????StringBuilder?sb?=?new?StringBuilder();
????????????//?find?a?record
????????????string?graveInfo?=?string.Empty;
????????????for?(uint?i?=?0;?i?<?iFeature;?i++)
????????????{
????????????????GisSharpBlog.NetTopologySuite.Geometries.Geometry?oPoly?=?SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(oShape.GetFeature(i).Geometry,?new?GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory());
????????????????if?(oPt.Within(oPoly))
????????????????{
????????????????????if?(oShape.GetFeature(i)[someId].ToString().Length?>?0)
????????????????????{
???????????????????????return?BuildGraveInfoTable(name,?value);
????????????????????}
????????????????}
????????????????
????????????}
????????????return?string.emtpy;
????????}
?
這里把sharpfile的Geometry都轉換成了NTS 的,這樣,使用NTS的Within方法進行比較。sharpmap自己的方法在我的測試中是不能用的,希望大家在使用過程中做些嘗試,看看是否是我自己的代碼有問題,總之,我是用的NTS。
到這里,我們就實現了根據點來查詢對象數據的功能,我們只需要在shapefile中存儲一個attribute(比如對象的ID),然后取出來顯示出去就OK了。
同理的,我們也可以實現根據一個用戶ID來找到這個對象在地圖中的位置,并顯示在地圖中間。
代碼如下:
?
Code??public?SharpMap.Geometries.Point?GetPointByID(string?Id)
????????{
????????????SharpMap.Data.Providers.ShapeFile?oShape?=?(SharpMap.Data.Providers.ShapeFile)GetShapeFile(filePath);
????????????oShape.Open();
????????????uint?i?=?0;
????????????uint?iFeature?=?(uint)oShape.GetFeatureCount();
????????????SharpMap.Geometries.Point?oPt?=?null;
????????????for?(i?=?0;?i?<?iFeature;?i++)
????????????{
????????????????GisSharpBlog.NetTopologySuite.Geometries.Geometry?oPoly?=?SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(oShape.GetFeature(i).Geometry,?new?GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory());
????????????????if?(oShape.GetFeature(i)["Id"].ToString()?==?Id)
????????????????{
????????????????????oPt?=?new?SharpMap.Geometries.Point(oPoly.InteriorPoint.X,?oPoly.InteriorPoint.Y);
????????????????}
????????????}
????????????return?oPt;
????????}
找到這個點之后,設置一下控件的地圖的中心點,就OK了。
?ajaxMap.Map.Center = pCenter;
雖然東西很簡單,但是還是費了我很多功夫。很大一部分原因是因為sharpmap自己提供的方法不太完善,導致很多時間花費在了追蹤問題上。不過這種追蹤對理解開源的代碼也是很有好處的。
在這個例子中,我使用了遍歷地圖中所有feature的方法來定位一個對象,這樣非常的耗費資源,效率并不好。如果地圖對象比較少還可以,一旦超過一定的數量級,可能會出現性能問題。以后我會在這個基礎上進行改進,利用其它方法來實現這個功能(事實上我已經進行了一些嘗試,只是還沒有成功。如果有人成功了,希望給我一些建議,謝謝)。
今天就到這里,感謝大家的關注,希望多多拍磚,共同進步。
在下一篇中,我將和大家共同學習關于根據attribute的值來填充地圖上對象的顏色,設置他們的樣式以及一些有趣的小玩意兒。希望大家繼續關注,謝謝。
?
?
?
轉載于:https://www.cnblogs.com/GodSpeed/archive/2009/02/28/1400124.html
總結
以上是生活随笔為你收集整理的SharpMap学习(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HttpServletRequest 常
- 下一篇: 自己遇到oracle的错误记录