SharpMap学习(2)

在经过第一篇的简单学习之后,我们开始了解一些稍微有点儿意思的东西,进一步掌握和学习利用sharpmap进行开发的技巧。

这次,我们主要是跟大家一起学习一下如何根据地图上的一个点,来查询这个点所在的对象的信息,并显示到点击的位置。这非常有用,比如说一个想把一个房子显示在地图上,我们用鼠标一点,便知道这个房子里住的什么人,干什么的,以及其它相关信息。

同样的,我们还是使用sharpmap提供的ajax控件,环境和第一篇一模一样。但是这里,我们要引用一个叫做NetTopologySuite的类库。它经常和SharpMap一起使用,这次我们只使用其中的一个小部分,废话不多说,开始做。

这里我们使用asp.net ajax 1.0,首先引用了dll,并且拖上scripmanager并设置为EnablePageMethods=true,这样我们就可以在页面中写静态方法来实现AJAX。

在MapClicked方法(AjaxMapControl控件提供的方法,直接写在js中即可,表示单击的时候发生一些事情)中,我们调用我们写的js,根据两个点来返回一个字符串。这个字符串就是拼好的html,直接显示出来。

ContractedBlock.gif ExpandedBlockStart.gif Code
function MapClicked(event,obj)
ExpandedBlockStart.gifContractedBlock.gif    
{
        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源码如下)。

 

 

 

 

 

ContractedBlock.gif ExpandedBlockStart.gif 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了。主要代码如下:

ContractedBlock.gif ExpandedBlockStart.gif 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来找到这个对象在地图中的位置,并显示在地图中间。

代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过该课程的学习,主要掌握地理信息系统(GIS)概念,空间分析功能;开源GIS及内容;了解常见开源桌面、Web和移动GIS等各种平台软件功能和设计;学习开源开发方法和开源GIS项目设计。达到以下教学目的: 1、了解开源精神——自由、开放、共享,树立开源学习理念。掌握开源GIS设计方法和技术,重点掌握开源GIS软件的基本应用 2、通过对典型开源GIS项目的分析,重点学习GIS设计的基本内容:项目规划,组织管理,系统设计,编码技能和系统测试与维护 3、通过典型模式分析,掌握设计模式在GIS项目中的使用原则和方法以及技巧,难点是分析设计模式在GIS设计中应用 4、了解GIS应用性框架、插件式GIS、通用GIS解决方案设计等内容 课时1:试听 课时2:付费学员服务指引 课时3:1.GIS空间分析 课时4:2.开源软件 课时5:3.开源GIS课程 课时6:4.开源GIS实验环境 课时7:课件资料 课时8:1.PostgreSQL简介 课时9:2.空间数据库概述 课时10:3.PostGIS简介 课时11:4.PostGIS实践操作 课时12:课件资料 课时13:1.PostgreSQL扩展 课时14:2.PostgreSQL索引和PG的GIST注意事项 课时15:3.PostGIS raster 课时16:4.PostGIS开源开发 课时17:5.PostGIS栅格操作 课时18:6.实践操作 课时19:课件资料 课时20:1.PG企业应用 课时21:2.其他开源空间数据库 课时22:课件资料 课时23:1.QGIS简介 课时24:2.地图配准 课时25:3.GRASS TSP分析 课时26:4.实践操作 课时27:课件资料 课时28:1.GRASS栅格分析和影像分析 课时29:2.GRASS地图动画 课时30:3.GRASS TSP分析 课时31:课件资料 课时32:1.GRASS与PG的互链 课时33:2.GRASS开源开发 课时34:3.实践操作 课时35:课件资料 课时36:1.WEBGIS简述 课时37:2.WEBGIS模式和开源WEBGIS简介 课时38:3.CGI原理和编程 课时39:4.CGI模式WEBGIS-中国WEB地图 课时40:5.CGI模式WEBGIS-GeoMoose项目 课时41:课件资料 课时42:1.Mapserver项目(MIT) 课时43:2.Mapserver发布数据(1) 课时44:3.Mapserver发布数据(2) 课时45:4.Mapserver开发:两种开发方式 课时46:5.Mapserver应用 课时47:课件资料 课时48:1.GeoServer项目(GPL) 课时49:2.GeoServer体系特点(JavaServlet) 课时50:3.GeoServer体系特点和GeoServer发布数据 课时51:4.实践操作 课时52:课件资料 课时53:1.OGC OpenGIS 课时54:2.OGC OWS 课时55:3.SOA WEBGIS 课时56:4.实际操作 课时57:课件资料 课时58:1.开源移动GIS简介 课时59:2.gvSIG Mobile GIS 课时60:3.移动GIS开发模式 课时61:4.实践操作 课时62:《开源GIS》课程总结 课时63:课件资料 本课程为开源GIS视频课程的优化版(经改良过的完整版)。因此部分课程与该目录有出入,但是出入不大。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值