免费视频|新人指南|投诉删帖|广告合作|地信网APP下载

查看: 2164|回复: 2
收起左侧

[技术交流] 西南大学校园GIS平台

[复制链接]

45

主题

8272

铜板

17

好友

高级工程师

Rank: 9Rank: 9Rank: 9

积分
1122
QQ
发表于 2016-10-24 08:58 | 显示全部楼层 |阅读模式
系统架构是B/S,开发语言是C#、silverlight,开发平台是.NET,数据库为sqlserver,这是我读研究生时候自己做的作品,以自己的母校为地图,进行GIS相关的功能分析,核心的模块有:空间查询、GPS定位模拟、搜索模块、统计分析;其中说的不足之处,望各位指点出来。
     一、空间查询     
     整体思路:空间查询是用户在地图上框选一定范围,然后根据框选范围Geometry来进行query查询。框选利用Draw工具有多边形、矩形、圆线等方式。实现方式,前台界面设计:
<!--Toolbar工具栏-->
  1. <Grid x:Name="ToolbarGrid" HorizontalAlignment="Left"  VerticalAlignment="Top"  Width="600" Height="0" RenderTransformOrigin="0.5,0.5">
  2.                         <Grid.RenderTransform>
  3.                             <ScaleTransform x:Name="ToolbarGridScaleTransform" ScaleX="0" ScaleY="0" />
  4.                         </Grid.RenderTransform>
  5.                         <StackPanel Orientation="Vertical">
  6.                         <esriToolkit:Toolbar x:Name="MyToolbar" MaxItemHeight="40" MaxItemWidth="40"
  7.                            VerticalAlignment="Top" HorizontalAlignment="Left"
  8.                            Loaded="MyToolbar_Loaded"
  9.                            ToolbarItemClicked="MyToolbar_ToolbarItemClicked"
  10.                            ToolbarIndexChanged="MyToolbar_ToolbarIndexChanged"
  11.                            Width="600" Height="40">
  12.                             <esriToolkit:Toolbar.Items>
  13.                                 <esriToolkit:ToolbarItemCollection>
  14.                                     <!--Zoom in-->
  15.                                     <esriToolkit:ToolbarItem Text="放大">
  16.                                         <esriToolkit:ToolbarItem.Content>
  17.                                             <Image Source="Images/i_zoomin.png" Stretch="UniformToFill" Margin="3" />
  18.                                         </esriToolkit:ToolbarItem.Content>
  19.                                     </esriToolkit:ToolbarItem>
  20.                                     <!--Zoom out-->
  21.                                     <esriToolkit:ToolbarItem Text="缩小">
  22.                                         <esriToolkit:ToolbarItem.Content>
  23.                                             <Image Source="Images/i_zoomout.png" Stretch="UniformToFill" Margin="3" />
  24.                                         </esriToolkit:ToolbarItem.Content>
  25.                                     </esriToolkit:ToolbarItem>
  26.                                     <!--PolygonQuery-->
  27.                                     <esriToolkit:ToolbarItem Text="多边形查询">
  28.                                         <esriToolkit:ToolbarItem.Content>
  29.                                             <Image Source="Images/DrawPolygon.png" Stretch="UniformToFill" Margin="5"/>
  30.                                         </esriToolkit:ToolbarItem.Content>
  31.                                     </esriToolkit:ToolbarItem>
  32.                                     <!--Polyline-->
  33.                                     <esriToolkit:ToolbarItem Text="线查询">
  34.                                         <esriToolkit:ToolbarItem.Content>
  35.                                             <Image Source="Images/DrawPolyline.png" Stretch="UniformToFill" Margin="5"/>
  36.                                         </esriToolkit:ToolbarItem.Content>
  37.                                     </esriToolkit:ToolbarItem>
  38.                                     <!--RectangleQuery-->
  39.                                     <esriToolkit:ToolbarItem Text="矩形查询">
  40.                                         <esriToolkit:ToolbarItem.Content>
  41.                                             <Image Source="Images/DrawRectangle.png" Stretch="UniformToFill" Margin="5"/>
  42.                                         </esriToolkit:ToolbarItem.Content>
  43.                                     </esriToolkit:ToolbarItem>
  44.                                 </esriToolkit:ToolbarItemCollection>
  45.                             </esriToolkit:Toolbar.Items>
  46.                         </esriToolkit:Toolbar>
  47.                         <TextBlock x:Name="StatusTextBlock" FontWeight="Bold" HorizontalAlignment="Center"/>
  48.                     </StackPanel>
  49.                 </Grid>
复制代码
         这里只讲空间查询部分,其他的距离量算、面积量算等具体见源代码。
          后台代码实现:
  1. public MainPageII() //构造函数初始化
  2.          {

  3.             //初始化MyDrawObject,draw工具
  4.             MyDrawObject = new Draw(MyMap)
  5.             {
  6.                 FillSymbol = DefaultFillSymbol, //初始化默认的填充颜色
  7.                 LineSymbol = DefaultLineSymbol //初始化默认的线颜色
  8.             };

  9.             MyDrawObject.DrawComplete += myDrawObject_DrawComplete; //draw完成触发函数,为了获取框选的范围geometry结果
  10.             MyDrawObject.DrawBegin += myDrawObject_DrawBegin; //draw之前触发函数,设置一些画之前的动作

  11.           }

  12.          private void myDrawObject_DrawBegin(object sender, EventArgs args)
  13.         {
  14.             GraphicsLayer graphicsLayer = MyMap.Layers["MapTipGraphicsLayer"] as GraphicsLayer;//设置GraphicsLayer
  15.             graphicsLayer.ClearGraphics();//draw之前,清空所有的graphics
  16.         }

  17.        ////////////////////////下面是实现工具栏的功能
  18.         private void myDrawObject_DrawComplete(object sender, DrawEventArgs args)
  19.         {
  20.             if (toolMode == "Rectangle_Query")//toolMode变量来判断是哪种模式框选,此处为矩形,其他框选模式原理是一样的,这里不再写出来
  21.             {
  22.                 GraphicsLayer graphicsLayer = MyMap.Layers["MapTipGraphicsLayer"] as GraphicsLayer;
  23.                 ESRI.ArcGIS.Client.Geometry.Envelope clickEnvelope = args.Geometry as Envelope;//获取几何范围geometry
  24.                 //先判断一下是矢量地图还是遥感地图
  25.                 if (rasterMap.IsChecked == true)
  26.                 {
  27.                     graphicsLayer.ClearGraphics();
  28.                 }
  29.                 else
  30.                 {
  31.                     graphicsLayer.ClearGraphics();
  32.                     ESRI.ArcGIS.Client.Graphic graphic = new ESRI.ArcGIS.Client.Graphic() //定义框选出来的矩形样式颜色
  33.                     {
  34.                         Geometry = clickEnvelope,
  35.                         Symbol = DefaultFillSymbol
  36.                     };
  37.                     graphicsLayer.Graphics.Add(graphic);//添加框选出来的图形显示在地图上
  38.                 }
  39.                 QueryTask queryTask = new QueryTask("http://192.168.1.4/arcgis/rest/services/SWUMap/MapServer/9");//定义QueryTask
  40.                 queryTask.ExecuteCompleted += QueryTask1_ExecuteCompleted; //query查询结果

  41.                 queryTask.Failed += QueryTask_Failed;//query查询失败
  42.                 Query query = new ESRI.ArcGIS.Client.Tasks.Query(); //定义query对象
  43.                 // Specify fields to return from query
  44.                 query.OutFields.AddRange(new string[] { "ID", "NAME", "Area", "Length", "X", "Y", "ImagePath" });//设置query条件
  45.                 //query.OutFields.Add("*");
  46.                 query.Where = "1=1";
  47.                 query.Geometry = args.Geometry;//几何条件
  48.                 query.ReturnGeometry = true;
  49.                 queryTask.ExecuteAsync(query);//执行query查询
  50.                 Binding resultFeaturesBinding = new Binding("LastResult");/query查询结果值获取,绑定在datagrid表格用
  51.                 resultFeaturesBinding.Source = queryTask;
  52.                 Find_QueryDetailsDataGrid.SetBinding(DataGrid.ItemsSourceProperty, resultFeaturesBinding);//获取的查询结果值绑定在datagrid表格
  53.                 ShowFindQueryWindow.Begin();
  54.             }
  55.         }

  56.         /// <summary>
  57.         /// 显示选择元素颜色
  58.         /// </summary>
  59.         /// <param name="sender"></param>
  60.         /// <param name="args"></param>
  61.         private void QueryTask1_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
  62.         {
  63.             FeatureSet Query_featureSet = args.FeatureSet;//获取到查询结果集合
  64.             GraphicsLayer graphicsLayer = MyMap.Layers["MapTipGraphicsLayer"] as GraphicsLayer;
  65.             if (Query_featureSet == null || Query_featureSet.Features.Count < 1)
  66.             {
  67.                 information.Text = "没有查询记录!";
  68.                 ShowImageRoot.Begin();
  69.                 return;
  70.             }
  71.             if (Query_featureSet != null && Query_featureSet.Features.Count > 0)
  72.             {
  73.                 foreach (Graphic feature in Query_featureSet.Features)
  74.                 {
  75.                     //先判断一下是矢量地图还是遥感地图
  76.                     if (rasterMap.IsChecked == true)
  77.                     {
  78.                         feature.Symbol = LayoutRoot.Resources["RemotePicture"] as ESRI.ArcGIS.Client.Symbols.PictureMarkerSymbol;//定义符号颜色样式
  79.                         feature.Geometry = new MapPoint(Convert.ToDouble(feature.Attributes["X"]), Convert.ToDouble(feature.Attributes["Y"]));
  80.                         graphicsLayer.Graphics.Add(feature);
  81.                         RemotePictureStoryboard.Begin();
  82.                     }
  83.                     else
  84.                     {
  85.                         feature.Symbol = LayoutRoot.Resources["ParcelSymbol"] as FillSymbol;//定义符号颜色样式
  86.                         graphicsLayer.Graphics.Insert(0, feature);//查询结果的几何图形显示在地图上
  87.                     }
  88.                 }
  89.             }
  90.         }
复制代码
二、搜索模块,主要包括路径搜索、关键字搜索、范围搜索
            
      1、关键字搜索,就是普通的query查询,其实应该用locator地理编码服务来实现的,当时自己水平有限,没能使用。把所有兴趣的信息集合在一个图层里面,然后发布地图服务,这样用query查询方式可以达到跟locator一样的目的。
      这里贴上核心后台代码好了,前台界面很简单就是一个文本框输入和按钮。
  1.                 QueryTask queryTask = new QueryTask("http://192.168.1.4/arcgis/rest/services/SWUMap/MapServer/9");//定义QueryTask
  2.                 queryTask.ExecuteCompleted += QueryTask2_ExecuteCompleted; //query查询结果

  3.                 Query query = new ESRI.ArcGIS.Client.Tasks.Query(); //定义query对象
  4.                 query.OutFields.AddRange(new string[] { "ID", "NAME", "Area", "Length", "X", "Y", "ImagePath" });//设置query条件
  5.                 query.text =****;//文本框获取的文本值
  6.                 query.ReturnGeometry = true;
  7.                 queryTask.ExecuteAsync(query);//执行query查询
复制代码
很类似框选查询的query,不过是设置条件换了,geometry换为text,查询结果一样是在 queryTask.ExecuteCompleted里面获取,获取到关键字查询的结果然后定位到其地理位置显示在地图上。
      2、范围搜索,这里用buffer分析方式来实现的,利用buffer获取到几何范围geometry,然后再利用query方式来实现,这里很类似空间查询部分的框选查询,不同的是获取geometry方式不太一样,一个是draw,一个是buffer。
            此处是用地图单击事件获取某点,然后利用某点为中心来buffer的,贴上buffer部分代码,后果query代码跟空间查询部分是一样的。
             GeometryService _geometryService;
            (1)初始化函数定义
             _geometryService = new GeometryService("http://192.168.1.4/arcgis/rest/services/Geometry/GeometryServer");
            _geometryService.BufferCompleted += GeometryService_BufferCompleted;
            _geometryService.Failed += GeometryService_Failed;   
(2) 地图单击事件函数
  1. ////先判断一下,输入条件是否为空
  2.                 if (Buffertextbox.Text == "")
  3.                 { //MessageBox.Show("请您输入范围搜索条件!");
  4.                     information.Text = "请您输入范围搜索条件!";
  5.                     ShowImageRoot.Begin();
  6.                   return;
  7.                 }
  8.                 GraphicsLayer graphicsLayer = MyMap.Layers["MapTipGraphicsLayer"] as GraphicsLayer;
  9.                 graphicsLayer.ClearGraphics();
  10.                 _geometryService.CancelAsync();
  11.                 _queryTask.CancelAsync();
  12.                 Graphic stop = new Graphic();
  13.                 if (rasterMap.IsChecked == true)
  14.                 {
  15.                     stop.Symbol = RemotePicture1;
  16.                 }
  17.                 else
  18.                 {
  19.                     stop.Symbol = StopSymbol;
  20.                 }
  21.                 stop.Geometry = e.MapPoint;//获取地图点坐标
  22.                 stop.Geometry.SpatialReference = MyMap.SpatialReference;
  23.                 stop.SetZIndex(2);
  24.                 graphicsLayer.Graphics.Add(stop);
  25.                 // Use a projection appropriate for your area of interest
  26.                 ESRI.ArcGIS.Client.Tasks.BufferParameters bufferParams = new ESRI.ArcGIS.Client.Tasks.BufferParameters()
  27.                 {
  28.                     //BufferSpatialReference = new SpatialReference(4326),
  29.                     BufferSpatialReference = new SpatialReference(32648),
  30.                     OutSpatialReference = MyMap.SpatialReference,
  31.                     Unit = LinearUnit.Meter//设置地图单位
  32.                 };
  33.                 double R = Convert.ToDouble(Buffertextbox.Text);//buffer半径
  34.                 bufferParams.Distances.Add(R);
  35.                 bufferParams.Features.Add(stop);
  36.                 _geometryService.BufferAsync(bufferParams); //执行缓冲分析
复制代码
   (3)获取buffer范围结果函数,然后利用geomerey来query查询
  1. private void GeometryService_BufferCompleted(object sender, GraphicsEventArgs args)
  2.         {
  3.             Graphic bufferGraphic = new Graphic();
  4.             bufferGraphic.Geometry = args.Results[0].Geometry;//获取buffer范围geometry
  5.             bufferGraphic.Symbol = BufferSymbol;//定义buffer符号
  6.             bufferGraphic.SetZIndex(1);
  7.             GraphicsLayer graphicsLayer = MyMap.Layers["GLayer"] as GraphicsLayer;
  8.             graphicsLayer.Graphics.Add(bufferGraphic);
  9.             ESRI.ArcGIS.Client.Tasks.Query query = new ESRI.ArcGIS.Client.Tasks.Query();
  10.             //query.OutFields.Add("*");
  11.             query.OutFields.AddRange(new string[] { "DW", "Shape", "ID", "Area", "Length", "NAME","X","Y","ImagePath" });
  12.             query.ReturnGeometry = true;
  13.             query.Where = "1=1";
  14.             query.Geometry = bufferGraphic.Geometry;
  15.             _queryTask.ExecuteAsync(query);
  16.             Binding resultFeaturesBinding = new Binding("LastResult.Features");
  17.             resultFeaturesBinding.Source = _queryTask;
  18.             huanchongqujieguo.SetBinding(DataGrid.ItemsSourceProperty, resultFeaturesBinding);
  19.            // BufferResultWindow.IsOpen = true;
  20.             //huanchongqujieguo.Visibility = Visibility.Visible;
  21.             ShowBufferResultWindow.Begin();
  22.         }
复制代码
      3、路径搜索,最短路径和最优路径,重点详细描述最短路径,最优路径是在最短的路径基础上改造的,这里篇数问题,不再讲。
           (1)最短路径,界面是两个文本框和查询按钮,这里不贴了,贴上核心代码:
  1. //下面是实现路径添加障碍点网络分析
  2.         MapPoint MapPointRoute1, MapPointRoute2;
  3.         RouteTask _routeTask;
  4.         List<Graphic> _stops = new List<Graphic>();
  5.         List<Graphic> _barriers = new List<Graphic>();
  6.         RouteParameters _routeParams = new RouteParameters();
  7.         /////定义Direction
  8.         Graphic _activeSegmentGraphic;
  9.         DirectionsFeatureSet _directionsFeatureSet;

  10.          /// <summary>
  11.         /// 最短路径分析初始化
  12.         /// </summary>
  13.         private void MyShortPathToChoice()
  14.         {
  15.             _routeTask = new RouteTask("http://192.168.1.4/arcgis/rest/services/SWUMap/NAServer/Route");
  16.             _routeTask.SolveCompleted += routeTask_SolveCompleted;
  17.             _routeTask.Failed += routeTask_Failed;
  18.             _routeParams.Stops = _stops;
  19.             _routeParams.Barriers = _barriers;
  20.             _routeParams.UseTimeWindows = false;
  21.             ////定义Direction的
  22.             _routeParams.ReturnRoutes = true;/////
  23.             _routeParams.ReturnDirections = true;
  24.             _routeParams.DirectionsLengthUnits = esriUnits.esriMiles;
  25.         }

  26.           ///////////////执行路径分析  

  27.        if (_stops.Count > 1)
  28.             {
  29.                // GraphicsLayer stopsLayer = MyMap.Layers["MyStopsGraphicsLayer"] as GraphicsLayer;
  30.                 if (_routeTask.IsBusy)
  31.                 {
  32.                     _routeTask.CancelAsync();
  33.                     stopsLayer.Graphics.RemoveAt(stopsLayer.Graphics.Count - 1);
  34.                 }
  35.                 _routeTask.SolveAsync(_routeParams);


  36.             }

  37.         ///////路径分析结果

  38.        private void routeTask_SolveCompleted(object sender, RouteEventArgs e)
  39.         {
  40.             GraphicsLayer routeLayer = MyMap.Layers["MyRouteGraphicsLayer"] as GraphicsLayer;
  41.             if (e.RouteResults.Count() > 0 && Which_Path1 == "ShortPath")
  42.             {
  43.                 ////先清空DirectionsStackPanel
  44.                 DirectionsStackPanel.Children.Clear();
  45.                 RouteResult routeResult = e.RouteResults[0];
  46.                 ////定义Direction
  47.                 _directionsFeatureSet = routeResult.Directions;
  48.                 routeResult.Route.Geometry = _directionsFeatureSet.MergedGeometry;
  49.                 //routeResult.Route.Symbol = RouteSymbol;
  50.                 routeResult.Route.Symbol = LayoutRoot.Resources["RouteSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol;
  51.                 routeLayer.Graphics.Clear();
  52.                 Graphic lastRoute = routeResult.Route;
  53.                 //decimal totalLength = (decimal)lastRoute.Attributes["Shape_Length"];
  54.                 decimal totalLength = (decimal)lastRoute.Attributes["Total_Length"];
  55.                 string length = string.Format("{0} Meters", totalLength.ToString("#0.000"));
  56.                 Total_Length.Text = length;
  57.                 //decimal totalTime = (decimal)lastRoute.Attributes["Total_Time"];
  58.                 string tip = string.Format("{0} minutes", (totalLength/100).ToString("#0.000"));
  59.                 Total_Time.Text = tip;
  60.                 routeLayer.Graphics.Add(lastRoute);
  61.                 ////Direction
  62.                 int i = 1;
  63.                 foreach (Graphic graphic in _directionsFeatureSet.Features)
  64.                 {
  65.                     System.Text.StringBuilder text = new System.Text.StringBuilder();
  66.                     text.AppendFormat("{0}. {1}", i, graphic.Attributes["text"]);
  67.                     if (i > 1 && i < _directionsFeatureSet.Features.Count)
  68.                     {
  69.                         string distance = (Convert.ToDouble(graphic.Attributes["length"])*1609.329).ToString();
  70.                        // string distance = graphic.Attributes["length"].ToString();
  71.                        // string distance = graphic.Attributes["length"].ToString();
  72.                         string time = null;
  73.                         if (graphic.Attributes.ContainsKey("time"))
  74.                         {
  75.                             //time = FormatTime(Convert.ToDouble(graphic.Attributes["time"]));
  76.                             time = graphic.Attributes["time"].ToString();
  77.                         }
  78.                         if (!string.IsNullOrEmpty(distance) || !string.IsNullOrEmpty(time))
  79.                             text.Append(" (");
  80.                         text.Append(distance);
  81.                         if (!string.IsNullOrEmpty(distance) && !string.IsNullOrEmpty(time))
  82.                             text.Append(", ");
  83.                         text.Append(time);
  84.                         if (!string.IsNullOrEmpty(distance) || !string.IsNullOrEmpty(time))
  85.                             text.Append(")");
  86.                     }
  87.                     TextBlock textBlock = new TextBlock() { Text = text.ToString(), Tag = graphic, Margin = new Thickness(4), Cursor = Cursors.Hand };
  88.                     textBlock.MouseLeftButtonDown += new MouseButtonEventHandler(directionsSegment_MouseLeftButtonDown);
  89.                     DirectionsStackPanel.Children.Add(textBlock);
  90.                     i++;
  91.                 }
  92.                 MyMap.ZoomTo(Expand(_directionsFeatureSet.Extent));
  93.             }                 
  94.         }  

  95.      private void directionsSegment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  96.         {
  97.             TextBlock textBlock = sender as TextBlock;
  98.             Graphic feature = textBlock.Tag as Graphic;
  99.             MyMap.ZoomTo(Expand(feature.Geometry.Extent));
  100.             if (_activeSegmentGraphic == null)
  101.             {
  102.                 _activeSegmentGraphic = new Graphic() { Symbol = LayoutRoot.Resources["SegmentSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol };
  103.                 GraphicsLayer graphicsLayer = MyMap.Layers["MyRouteGraphicsLayer"] as GraphicsLayer;
  104.                 graphicsLayer.Graphics.Add(_activeSegmentGraphic);
  105.             }
  106.             _activeSegmentGraphic.Geometry = feature.Geometry;
  107.         }
  108.         private void stackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  109.         {
  110.             if (_directionsFeatureSet != null)
  111.             {
  112.                 GraphicsLayer graphicsLayer = MyMap.Layers["MyRouteGraphicsLayer"] as GraphicsLayer;
  113.                 MyMap.ZoomTo(Expand(_directionsFeatureSet.Extent));1n
  114.             }
  115.         }
  116.         private Envelope Expand(Envelope e)
  117.         {
  118.             double factor = 0.6;
  119.             MapPoint centerMapPoint = e.GetCenter();
  120.             return new Envelope(centerMapPoint.X - e.Width * factor, centerMapPoint.Y - e.Height * factor,
  121.                 centerMapPoint.X + e.Width * factor, centerMapPoint.Y + e.Height * factor);
  122.         }  
复制代码
       三、GPS模拟定位,这里说说思路好了,具体见源代码。主要是模拟校车每个时刻的地位Point,然后再描绘出来连接成线line,最后添加再地图上显示出来。应用到arcgis api的对象point、line、graphic、geometry、graphiclayer等等。
       、统计分析,这里不描述了,具体见源代码。

GIS作品:百度搜索:GIS之家(https://shop116521643.taobao.com/shop/view_shop.htm);
QQ兴趣部落GIS技术交流:gis之家(http://buluo.qq.com/p/barindex.html?bid=327395);
GIS毕业设计&项目承接群:238339408;
GIS技术交流群:432512093

0

主题

367

铜板

2

好友

技术员

Rank: 3Rank: 3

积分
22
发表于 2016-10-29 21:28 | 显示全部楼层
你好  校友  地科院的?
回复 支持 反对

使用道具 举报

45

主题

8272

铜板

17

好友

高级工程师

Rank: 9Rank: 9Rank: 9

积分
1122
QQ
 楼主| 发表于 2016-10-30 09:10 | 显示全部楼层
你好,是呢地科院的,你是学生还是毕业的?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

在线客服
快速回复 返回顶部 返回列表