程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> SharpMap學習(2)

SharpMap學習(2)

編輯:關於.NET

在經過第一篇的簡單學習之後,我們開始了解一些稍微有點兒意思的東西,進一步掌握和學習利用 sharpmap進行開發的技巧。

這次,我們主要是跟大家一起學習一下如何根據地圖上的一個點,來查詢這個點所在的對象的信息, 並顯示到點擊的位置。這非常有用,比如說一個想把一個房子顯示在地圖上,我們用鼠標一點,便知道這 個房子裡住的什麼人,干什麼的,以及其它相關信息。

同樣的,我們還是使用sharpmap提供的ajax控件,環境和第一篇一模一樣。但是這裡,我們要引用一 個叫做NetTopologySuite的類庫。它經常和SharpMap一起使用,這次我們只使用其中的一個小部分,廢話 不多說,開始做。

這裡我們使用asp.net ajax 1.0,首先引用了dll,並且拖上scripmanager並設置為 EnablePageMethods=true,這樣我們就可以在頁面中寫靜態方法來實現AJAX。

在MapClicked方法(AjaxMapControl控件提供的方法,直接寫在js中即可,表示單擊的時候發生一些 事情)中,我們調用我們寫的js,根據兩個點來返回一個字符串。這個字符串就是拼好的html,直接顯示 出來。

function 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源碼 如下)。

<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了。主要代碼如下:

   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來找到這個對象在地圖中的位置,並顯示在地圖中間。

代碼如下:

  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的值來填充地圖上對象的顏色,設置他們的樣式 以及一些有趣的小玩意兒。希望大家繼續關注,謝謝。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved