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

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

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

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

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

Code
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源码如下)。

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)相关推荐

  1. C# SharpMap 学习总结

    SharpMap V1.1 For Web教程系列之--地图展示 SharpMap V1.1 For Web教程系列之--地图展示 开篇先说本次的开发环境吧.采用Vs2010,.Net Framewo ...

  2. SharpMap学习:Map

      Map类 是核心类 包含着各个图层layers的引用 GetMap进行渲染 除了GetMap渲染方法外 还有 1.Dispose方法 对layers集合内每个图层进行dispose 最后清空集合 ...

  3. SharpMap在web上的应用

    最近公司用SharpMap做了一个做桌面程序,它是一个开源的Gis项目,功能还可以,最大的特点就是简单易用,这里介绍下怎么在web下使用: 这次我们根据demo先了解一下如何show一个地图.这是最基 ...

  4. java入门 慕路径,Java入门基础知识总结学习教程大全【必看经典】

    类型的表达式,是循环条件,表达式3是党执行了一遍循环之后,修改控制循环的变量值. ??? for语句的执行过程是这样的:首先计算表达式1,完成必要的初始化工作:然后判断表达式2的值,如果表达式的值为t ...

  5. Java EE学习心得

    –Java EE学习心得   1.    称为编程专家的秘诀是: 思考-----编程--------思考------编程--.. 编程不能一步到位,不能一上来就编,必须先思考如何写,怎样写?然后再编程 ...

  6. FastAI 2019课程学习笔记 lesson 2:自行获取数据并创建分类器

    文章目录 数据获取 google_images_download 的安装和使用 挂载google 个人硬盘到Google colab中 删除不能打开文件 创建ImageDataBunch 训练模型 解 ...

  7. FastAI 课程学习笔记 lesson 1:宠物图片分类

    文章目录 代码解析 神奇的"%" 导入fastAI 库 下载解压数据集 untar_data 获取帮助文档 help() ? ?? doc 设置路径 get_image_files ...

  8. 深度学习学习指南-工具篇

    colab Colab是由Google提供的云计算服务,通过它可以让开发者很方便的使用google的免费资源(CPU.GPU.TPU)来训练自己的模型. 学习经验总结 如何使用命令行? 通过!+cmd ...

  9. Redis学习之路(一)--下载安装redis

    redis学习之路--下载安装redis windows安装redis 1.下载redis 2.安装 3.查看是否安装成功 windows安装redis 1.下载redis 网址:https://gi ...

最新文章

  1. 使用C++ stringstream来进行数据类型转换
  2. CentOS安装nmap端口查看工具
  3. Java中几种日期格式相互转换
  4. javascript设计模式之外观模式
  5. keil stm32标准库放在哪里_STM32之PWM
  6. 如果被问到分布式锁,应该怎样回答?
  7. idea 调试java技巧_Intellij IDEA Debug 调试技巧
  8. 机器学习- 吴恩达Andrew Ng Week10 知识总结 Large scale machine learning
  9. Device disconnected
  10. (1.4.5)字符串类
  11. javase扎金花程序
  12. SEG1数字中继模块(中继网关) 产品型号:SEG1
  13. 静态成员和非静态成员的区别是什么?
  14. 推荐多款免费的开源建站系统和内容管理系统
  15. 图像特征中的几何不变矩:Hu矩
  16. 外包岗位对于程序员有什么优势?
  17. Oracle获取上一年的时间
  18. 线程钩子HookC#实例
  19. 9.6 Python 全课程总结和学习展望
  20. mybatis 中if关于数字的判断

热门文章

  1. 乐玩插件和大漠插件哪个好_用好这5款Chrome插件,大幅提升你的生产力
  2. PyCharm的光标插入与覆盖模式
  3. java图形界面_Java自学-图形界面 面板
  4. linux使用ntp时间同步
  5. python3读取网页_python3+selenium获取页面加载的所有静态资源文件链接操作
  6. fpga如何约束走线_如何正确的约束时钟—Vivado优化到关键路径
  7. matlab hashset,MATLAB集合操作
  8. 第三方软件源_手机上的天气软件哪个更准确?
  9. 怎么取消苹果手机自动续费_手机 App 自动续费套路多?我们要如何取消?
  10. python前端界面模板_Python编程flask使用页面模版的方法