SharpMap学习(2)
在經(jīng)過(guò)第一篇的簡(jiǎn)單學(xué)習(xí)之后,我們開始了解一些稍微有點(diǎn)兒意思的東西,進(jìn)一步掌握和學(xué)習(xí)利用sharpmap進(jìn)行開發(fā)的技巧。
這次,我們主要是跟大家一起學(xué)習(xí)一下如何根據(jù)地圖上的一個(gè)點(diǎn),來(lái)查詢這個(gè)點(diǎn)所在的對(duì)象的信息,并顯示到點(diǎn)擊的位置。這非常有用,比如說(shuō)一個(gè)想把一個(gè)房子顯示在地圖上,我們用鼠標(biāo)一點(diǎn),便知道這個(gè)房子里住的什么人,干什么的,以及其它相關(guān)信息。
同樣的,我們還是使用sharpmap提供的ajax控件,環(huán)境和第一篇一模一樣。但是這里,我們要引用一個(gè)叫做NetTopologySuite的類庫(kù)。它經(jīng)常和SharpMap一起使用,這次我們只使用其中的一個(gè)小部分,廢話不多說(shuō),開始做。
這里我們使用asp.net ajax 1.0,首先引用了dll,并且拖上scripmanager并設(shè)置為EnablePageMethods=true,這樣我們就可以在頁(yè)面中寫靜態(tài)方法來(lái)實(shí)現(xiàn)AJAX。
在MapClicked方法(AjaxMapControl控件提供的方法,直接寫在js中即可,表示單擊的時(shí)候發(fā)生一些事情)中,我們調(diào)用我們寫的js,根據(jù)兩個(gè)點(diǎn)來(lái)返回一個(gè)字符串。這個(gè)字符串就是拼好的html,直接顯示出來(lái)。
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);
????}
?
這個(gè)方法里面的SharpMap_GetRelatiovePosition和?SharpMap_PixelToMap方法根據(jù)鼠標(biāo)在屏幕上的坐標(biāo)計(jì)算出鼠標(biāo)點(diǎn)在地圖上的坐標(biāo),再調(diào)用我們自己寫的GetData方法即可。在GetData方法中,我們使用了PageMethods來(lái)調(diào)用一個(gè)后臺(tái)方法,并返回一個(gè)字符串。
?PageMethods.GetData(x, y, GetDataSuccess);
然后,在GetDataSuccess中調(diào)用一個(gè)寫好的用來(lái)顯示這些返回?cái)?shù)據(jù)的方法(此方法來(lái)自網(wǎng)絡(luò),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>
?需要指出的是,這個(gè)效果需要做一些初始化的工作:
?? <div id="toolTipLayer" style="position:absolute;visibility: hidden;z-index:10000">??? </div>
??? <script type="text/javascript">
??????? initToolTips();
??? </script>
這樣,我們?cè)谇芭_(tái)的工作就基本完成了。
當(dāng)然,如果想要更好看一些,再寫一個(gè)css幫助從后臺(tái)傳來(lái)的html進(jìn)行淡化。
?.clarity
??????? {
??????????? background-color:#4d7d99;
??????????? filter:alpha(opacity=80,Style=0);
????????}
OK,現(xiàn)在轉(zhuǎn)去后臺(tái)。
在根據(jù)兩個(gè)點(diǎn)查詢對(duì)象數(shù)據(jù)時(shí),我們首先要初始化需要初始化shapefile,也就是你要查詢的那個(gè)層的數(shù)據(jù)源。
new SharpMap.Data.Providers.ShapeFile(filepath true);
然后遍歷shapefile里面的每一個(gè)feature,對(duì)比傳入的點(diǎn)和feature所在的Geometry,如果傳入的點(diǎn)在feature所在Geometry之內(nèi)(within方法)的話,就讀取當(dāng)前feature的一個(gè)attribute(通常是某個(gè)業(yè)務(wù)對(duì)象的ID),這樣,根據(jù)這個(gè)ID就能取到業(yè)務(wù)對(duì)象的值,然后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都轉(zhuǎn)換成了NTS 的,這樣,使用NTS的Within方法進(jìn)行比較。sharpmap自己的方法在我的測(cè)試中是不能用的,希望大家在使用過(guò)程中做些嘗試,看看是否是我自己的代碼有問(wèn)題,總之,我是用的NTS。
到這里,我們就實(shí)現(xiàn)了根據(jù)點(diǎn)來(lái)查詢對(duì)象數(shù)據(jù)的功能,我們只需要在shapefile中存儲(chǔ)一個(gè)attribute(比如對(duì)象的ID),然后取出來(lái)顯示出去就OK了。
同理的,我們也可以實(shí)現(xiàn)根據(jù)一個(gè)用戶ID來(lái)找到這個(gè)對(duì)象在地圖中的位置,并顯示在地圖中間。
代碼如下:
?
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;
????????}
找到這個(gè)點(diǎn)之后,設(shè)置一下控件的地圖的中心點(diǎn),就OK了。
?ajaxMap.Map.Center = pCenter;
雖然東西很簡(jiǎn)單,但是還是費(fèi)了我很多功夫。很大一部分原因是因?yàn)閟harpmap自己提供的方法不太完善,導(dǎo)致很多時(shí)間花費(fèi)在了追蹤問(wèn)題上。不過(guò)這種追蹤對(duì)理解開源的代碼也是很有好處的。
在這個(gè)例子中,我使用了遍歷地圖中所有feature的方法來(lái)定位一個(gè)對(duì)象,這樣非常的耗費(fèi)資源,效率并不好。如果地圖對(duì)象比較少還可以,一旦超過(guò)一定的數(shù)量級(jí),可能會(huì)出現(xiàn)性能問(wèn)題。以后我會(huì)在這個(gè)基礎(chǔ)上進(jìn)行改進(jìn),利用其它方法來(lái)實(shí)現(xiàn)這個(gè)功能(事實(shí)上我已經(jīng)進(jìn)行了一些嘗試,只是還沒(méi)有成功。如果有人成功了,希望給我一些建議,謝謝)。
今天就到這里,感謝大家的關(guān)注,希望多多拍磚,共同進(jìn)步。
在下一篇中,我將和大家共同學(xué)習(xí)關(guān)于根據(jù)attribute的值來(lái)填充地圖上對(duì)象的顏色,設(shè)置他們的樣式以及一些有趣的小玩意兒。希望大家繼續(xù)關(guān)注,謝謝。
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/GodSpeed/archive/2009/02/28/1400124.html
總結(jié)
以上是生活随笔為你收集整理的SharpMap学习(2)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: HttpServletRequest 常
- 下一篇: 自己遇到oracle的错误记录