西南大学校园GIS平台
系统架构是B/S,开发语言是C#、silverlight,开发平台是.NET,数据库为sqlserver,这是我读研究生时候自己做的作品,以自己的母校为地图,进行GIS相关的功能分析,核心的模块有:空间查询、GPS定位模拟、搜索模块、统计分析;其中说的不足之处,望各位指点出来。
一、空间查询
整体思路:空间查询是用户在地图上框选一定范围,然后根据框选范围Geometry来进行query查询。框选利用Draw工具有多边形、矩形、圆线等方式。实现方式,前台界面设计:
<!--Toolbar工具栏-->
<Grid x:Name="ToolbarGrid" HorizontalAlignment="Left" VerticalAlignment="Top" Width="600" Height="0" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<ScaleTransform x:Name="ToolbarGridScaleTransform" ScaleX="0" ScaleY="0" />
</Grid.RenderTransform>
<StackPanel Orientation="Vertical">
<esriToolkit:Toolbar x:Name="MyToolbar" MaxItemHeight="40" MaxItemWidth="40"
VerticalAlignment="Top" HorizontalAlignment="Left"
Loaded="MyToolbar_Loaded"
ToolbarItemClicked="MyToolbar_ToolbarItemClicked"
ToolbarIndexChanged="MyToolbar_ToolbarIndexChanged"
Width="600" Height="40">
<esriToolkit:Toolbar.Items>
<esriToolkit:ToolbarItemCollection>
<!--Zoom in-->
<esriToolkit:ToolbarItem Text="放大">
<esriToolkit:ToolbarItem.Content>
<Image Source="Images/i_zoomin.png" Stretch="UniformToFill" Margin="3" />
</esriToolkit:ToolbarItem.Content>
</esriToolkit:ToolbarItem>
<!--Zoom out-->
<esriToolkit:ToolbarItem Text="缩小">
<esriToolkit:ToolbarItem.Content>
<Image Source="Images/i_zoomout.png" Stretch="UniformToFill" Margin="3" />
</esriToolkit:ToolbarItem.Content>
</esriToolkit:ToolbarItem>
<!--PolygonQuery-->
<esriToolkit:ToolbarItem Text="多边形查询">
<esriToolkit:ToolbarItem.Content>
<Image Source="Images/DrawPolygon.png" Stretch="UniformToFill" Margin="5"/>
</esriToolkit:ToolbarItem.Content>
</esriToolkit:ToolbarItem>
<!--Polyline-->
<esriToolkit:ToolbarItem Text="线查询">
<esriToolkit:ToolbarItem.Content>
<Image Source="Images/DrawPolyline.png" Stretch="UniformToFill" Margin="5"/>
</esriToolkit:ToolbarItem.Content>
</esriToolkit:ToolbarItem>
<!--RectangleQuery-->
<esriToolkit:ToolbarItem Text="矩形查询">
<esriToolkit:ToolbarItem.Content>
<Image Source="Images/DrawRectangle.png" Stretch="UniformToFill" Margin="5"/>
</esriToolkit:ToolbarItem.Content>
</esriToolkit:ToolbarItem>
</esriToolkit:ToolbarItemCollection>
</esriToolkit:Toolbar.Items>
</esriToolkit:Toolbar>
<TextBlock x:Name="StatusTextBlock" FontWeight="Bold" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
这里只讲空间查询部分,其他的距离量算、面积量算等具体见源代码。
后台代码实现:
public MainPageII() //构造函数初始化
{
//初始化MyDrawObject,draw工具
MyDrawObject = new Draw(MyMap)
{
FillSymbol = DefaultFillSymbol, //初始化默认的填充颜色
LineSymbol = DefaultLineSymbol //初始化默认的线颜色
};
MyDrawObject.DrawComplete += myDrawObject_DrawComplete; //draw完成触发函数,为了获取框选的范围geometry结果
MyDrawObject.DrawBegin += myDrawObject_DrawBegin; //draw之前触发函数,设置一些画之前的动作
}
private void myDrawObject_DrawBegin(object sender, EventArgs args)
{
GraphicsLayer graphicsLayer = MyMap.Layers["MapTipGraphicsLayer"] as GraphicsLayer;//设置GraphicsLayer
graphicsLayer.ClearGraphics();//draw之前,清空所有的graphics
}
下面是实现工具栏的功能
private void myDrawObject_DrawComplete(object sender, DrawEventArgs args)
{
if (toolMode == "Rectangle_Query")//toolMode变量来判断是哪种模式框选,此处为矩形,其他框选模式原理是一样的,这里不再写出来
{
GraphicsLayer graphicsLayer = MyMap.Layers["MapTipGraphicsLayer"] as GraphicsLayer;
ESRI.ArcGIS.Client.Geometry.Envelope clickEnvelope = args.Geometry as Envelope;//获取几何范围geometry
//先判断一下是矢量地图还是遥感地图
if (rasterMap.IsChecked == true)
{
graphicsLayer.ClearGraphics();
}
else
{
graphicsLayer.ClearGraphics();
ESRI.ArcGIS.Client.Graphic graphic = new ESRI.ArcGIS.Client.Graphic() //定义框选出来的矩形样式颜色
{
Geometry = clickEnvelope,
Symbol = DefaultFillSymbol
};
graphicsLayer.Graphics.Add(graphic);//添加框选出来的图形显示在地图上
}
QueryTask queryTask = new QueryTask("http://192.168.1.4/arcgis/rest/services/SWUMap/MapServer/9");//定义QueryTask
queryTask.ExecuteCompleted += QueryTask1_ExecuteCompleted; //query查询结果
queryTask.Failed += QueryTask_Failed;//query查询失败
Query query = new ESRI.ArcGIS.Client.Tasks.Query(); //定义query对象
// Specify fields to return from query
query.OutFields.AddRange(new string[] { "ID", "NAME", "Area", "Length", "X", "Y", "ImagePath" });//设置query条件
//query.OutFields.Add("*");
query.Where = "1=1";
query.Geometry = args.Geometry;//几何条件
query.ReturnGeometry = true;
queryTask.ExecuteAsync(query);//执行query查询
Binding resultFeaturesBinding = new Binding("LastResult");/query查询结果值获取,绑定在datagrid表格用
resultFeaturesBinding.Source = queryTask;
Find_QueryDetailsDataGrid.SetBinding(DataGrid.ItemsSourceProperty, resultFeaturesBinding);//获取的查询结果值绑定在datagrid表格
ShowFindQueryWindow.Begin();
}
}
/// <summary>
/// 显示选择元素颜色
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void QueryTask1_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
{
FeatureSet Query_featureSet = args.FeatureSet;//获取到查询结果集合
GraphicsLayer graphicsLayer = MyMap.Layers["MapTipGraphicsLayer"] as GraphicsLayer;
if (Query_featureSet == null || Query_featureSet.Features.Count < 1)
{
information.Text = "没有查询记录!";
ShowImageRoot.Begin();
return;
}
if (Query_featureSet != null && Query_featureSet.Features.Count > 0)
{
foreach (Graphic feature in Query_featureSet.Features)
{
//先判断一下是矢量地图还是遥感地图
if (rasterMap.IsChecked == true)
{
feature.Symbol = LayoutRoot.Resources["RemotePicture"] as ESRI.ArcGIS.Client.Symbols.PictureMarkerSymbol;//定义符号颜色样式
feature.Geometry = new MapPoint(Convert.ToDouble(feature.Attributes["X"]), Convert.ToDouble(feature.Attributes["Y"]));
graphicsLayer.Graphics.Add(feature);
RemotePictureStoryboard.Begin();
}
else
{
feature.Symbol = LayoutRoot.Resources["ParcelSymbol"] as FillSymbol;//定义符号颜色样式
graphicsLayer.Graphics.Insert(0, feature);//查询结果的几何图形显示在地图上
}
}
}
}
二、搜索模块,主要包括路径搜索、关键字搜索、范围搜索
1、关键字搜索,就是普通的query查询,其实应该用locator地理编码服务来实现的,当时自己水平有限,没能使用。把所有兴趣的信息集合在一个图层里面,然后发布地图服务,这样用query查询方式可以达到跟locator一样的目的。
这里贴上核心后台代码好了,前台界面很简单就是一个文本框输入和按钮。
QueryTask queryTask = new QueryTask("http://192.168.1.4/arcgis/rest/services/SWUMap/MapServer/9");//定义QueryTask
queryTask.ExecuteCompleted += QueryTask2_ExecuteCompleted; //query查询结果
Query query = new ESRI.ArcGIS.Client.Tasks.Query(); //定义query对象
query.OutFields.AddRange(new string[] { "ID", "NAME", "Area", "Length", "X", "Y", "ImagePath" });//设置query条件
query.text =****;//文本框获取的文本值
query.ReturnGeometry = true;
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) 地图单击事件函数
先判断一下,输入条件是否为空
if (Buffertextbox.Text == "")
{ //MessageBox.Show("请您输入范围搜索条件!");
information.Text = "请您输入范围搜索条件!";
ShowImageRoot.Begin();
return;
}
GraphicsLayer graphicsLayer = MyMap.Layers["MapTipGraphicsLayer"] as GraphicsLayer;
graphicsLayer.ClearGraphics();
_geometryService.CancelAsync();
_queryTask.CancelAsync();
Graphic stop = new Graphic();
if (rasterMap.IsChecked == true)
{
stop.Symbol = RemotePicture1;
}
else
{
stop.Symbol = StopSymbol;
}
stop.Geometry = e.MapPoint;//获取地图点坐标
stop.Geometry.SpatialReference = MyMap.SpatialReference;
stop.SetZIndex(2);
graphicsLayer.Graphics.Add(stop);
// Use a projection appropriate for your area of interest
ESRI.ArcGIS.Client.Tasks.BufferParameters bufferParams = new ESRI.ArcGIS.Client.Tasks.BufferParameters()
{
//BufferSpatialReference = new SpatialReference(4326),
BufferSpatialReference = new SpatialReference(32648),
OutSpatialReference = MyMap.SpatialReference,
Unit = LinearUnit.Meter//设置地图单位
};
double R = Convert.ToDouble(Buffertextbox.Text);//buffer半径
bufferParams.Distances.Add(R);
bufferParams.Features.Add(stop);
_geometryService.BufferAsync(bufferParams); //执行缓冲分析
(3)获取buffer范围结果函数,然后利用geomerey来query查询
private void GeometryService_BufferCompleted(object sender, GraphicsEventArgs args)
{
Graphic bufferGraphic = new Graphic();
bufferGraphic.Geometry = args.Results[0].Geometry;//获取buffer范围geometry
bufferGraphic.Symbol = BufferSymbol;//定义buffer符号
bufferGraphic.SetZIndex(1);
GraphicsLayer graphicsLayer = MyMap.Layers["GLayer"] as GraphicsLayer;
graphicsLayer.Graphics.Add(bufferGraphic);
ESRI.ArcGIS.Client.Tasks.Query query = new ESRI.ArcGIS.Client.Tasks.Query();
//query.OutFields.Add("*");
query.OutFields.AddRange(new string[] { "DW", "Shape", "ID", "Area", "Length", "NAME","X","Y","ImagePath" });
query.ReturnGeometry = true;
query.Where = "1=1";
query.Geometry = bufferGraphic.Geometry;
_queryTask.ExecuteAsync(query);
Binding resultFeaturesBinding = new Binding("LastResult.Features");
resultFeaturesBinding.Source = _queryTask;
huanchongqujieguo.SetBinding(DataGrid.ItemsSourceProperty, resultFeaturesBinding);
// BufferResultWindow.IsOpen = true;
//huanchongqujieguo.Visibility = Visibility.Visible;
ShowBufferResultWindow.Begin();
}
3、路径搜索,最短路径和最优路径,重点详细描述最短路径,最优路径是在最短的路径基础上改造的,这里篇数问题,不再讲。
(1)最短路径,界面是两个文本框和查询按钮,这里不贴了,贴上核心代码:
//下面是实现路径添加障碍点网络分析
MapPoint MapPointRoute1, MapPointRoute2;
RouteTask _routeTask;
List<Graphic> _stops = new List<Graphic>();
List<Graphic> _barriers = new List<Graphic>();
RouteParameters _routeParams = new RouteParameters();
/定义Direction
Graphic _activeSegmentGraphic;
DirectionsFeatureSet _directionsFeatureSet;
/// <summary>
/// 最短路径分析初始化
/// </summary>
private void MyShortPathToChoice()
{
_routeTask = new RouteTask("http://192.168.1.4/arcgis/rest/services/SWUMap/NAServer/Route");
_routeTask.SolveCompleted += routeTask_SolveCompleted;
_routeTask.Failed += routeTask_Failed;
_routeParams.Stops = _stops;
_routeParams.Barriers = _barriers;
_routeParams.UseTimeWindows = false;
定义Direction的
_routeParams.ReturnRoutes = true;/
_routeParams.ReturnDirections = true;
_routeParams.DirectionsLengthUnits = esriUnits.esriMiles;
}
///执行路径分析
if (_stops.Count > 1)
{
// GraphicsLayer stopsLayer = MyMap.Layers["MyStopsGraphicsLayer"] as GraphicsLayer;
if (_routeTask.IsBusy)
{
_routeTask.CancelAsync();
stopsLayer.Graphics.RemoveAt(stopsLayer.Graphics.Count - 1);
}
_routeTask.SolveAsync(_routeParams);
}
///路径分析结果
private void routeTask_SolveCompleted(object sender, RouteEventArgs e)
{
GraphicsLayer routeLayer = MyMap.Layers["MyRouteGraphicsLayer"] as GraphicsLayer;
if (e.RouteResults.Count() > 0 && Which_Path1 == "ShortPath")
{
先清空DirectionsStackPanel
DirectionsStackPanel.Children.Clear();
RouteResult routeResult = e.RouteResults[0];
定义Direction
_directionsFeatureSet = routeResult.Directions;
routeResult.Route.Geometry = _directionsFeatureSet.MergedGeometry;
//routeResult.Route.Symbol = RouteSymbol;
routeResult.Route.Symbol = LayoutRoot.Resources["RouteSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol;
routeLayer.Graphics.Clear();
Graphic lastRoute = routeResult.Route;
//decimal totalLength = (decimal)lastRoute.Attributes["Shape_Length"];
decimal totalLength = (decimal)lastRoute.Attributes["Total_Length"];
string length = string.Format("{0} Meters", totalLength.ToString("#0.000"));
Total_Length.Text = length;
//decimal totalTime = (decimal)lastRoute.Attributes["Total_Time"];
string tip = string.Format("{0} minutes", (totalLength/100).ToString("#0.000"));
Total_Time.Text = tip;
routeLayer.Graphics.Add(lastRoute);
Direction
int i = 1;
foreach (Graphic graphic in _directionsFeatureSet.Features)
{
System.Text.StringBuilder text = new System.Text.StringBuilder();
text.AppendFormat("{0}. {1}", i, graphic.Attributes["text"]);
if (i > 1 && i < _directionsFeatureSet.Features.Count)
{
string distance = (Convert.ToDouble(graphic.Attributes["length"])*1609.329).ToString();
// string distance = graphic.Attributes["length"].ToString();
// string distance = graphic.Attributes["length"].ToString();
string time = null;
if (graphic.Attributes.ContainsKey("time"))
{
//time = FormatTime(Convert.ToDouble(graphic.Attributes["time"]));
time = graphic.Attributes["time"].ToString();
}
if (!string.IsNullOrEmpty(distance) || !string.IsNullOrEmpty(time))
text.Append(" (");
text.Append(distance);
if (!string.IsNullOrEmpty(distance) && !string.IsNullOrEmpty(time))
text.Append(", ");
text.Append(time);
if (!string.IsNullOrEmpty(distance) || !string.IsNullOrEmpty(time))
text.Append(")");
}
TextBlock textBlock = new TextBlock() { Text = text.ToString(), Tag = graphic, Margin = new Thickness(4), Cursor = Cursors.Hand };
textBlock.MouseLeftButtonDown += new MouseButtonEventHandler(directionsSegment_MouseLeftButtonDown);
DirectionsStackPanel.Children.Add(textBlock);
i++;
}
MyMap.ZoomTo(Expand(_directionsFeatureSet.Extent));
}
}
private void directionsSegment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
TextBlock textBlock = sender as TextBlock;
Graphic feature = textBlock.Tag as Graphic;
MyMap.ZoomTo(Expand(feature.Geometry.Extent));
if (_activeSegmentGraphic == null)
{
_activeSegmentGraphic = new Graphic() { Symbol = LayoutRoot.Resources["SegmentSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol };
GraphicsLayer graphicsLayer = MyMap.Layers["MyRouteGraphicsLayer"] as GraphicsLayer;
graphicsLayer.Graphics.Add(_activeSegmentGraphic);
}
_activeSegmentGraphic.Geometry = feature.Geometry;
}
private void stackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (_directionsFeatureSet != null)
{
GraphicsLayer graphicsLayer = MyMap.Layers["MyRouteGraphicsLayer"] as GraphicsLayer;
MyMap.ZoomTo(Expand(_directionsFeatureSet.Extent));1n
}
}
private Envelope Expand(Envelope e)
{
double factor = 0.6;
MapPoint centerMapPoint = e.GetCenter();
return new Envelope(centerMapPoint.X - e.Width * factor, centerMapPoint.Y - e.Height * factor,
centerMapPoint.X + e.Width * factor, centerMapPoint.Y + e.Height * factor);
}
三、GPS模拟定位,这里说说思路好了,具体见源代码。主要是模拟校车每个时刻的地位Point,然后再描绘出来连接成线line,最后添加再地图上显示出来。应用到arcgis api的对象point、line、graphic、geometry、graphiclayer等等。
四、统计分析,这里不描述了,具体见源代码。
备注:
源代码下载:pan.baidu.com/s/1nt3JYDb
密码:sb3j
GIS技术交流QQ群:432512093
西南大学校园GIS平台相关推荐
- 校园二手平台使用说明
1.关注微信公共号,进入校园二手平台 2.点击公告号菜单栏的"校园交易"会进入校园二手平台,没有注册的用户会自动跳转到注册界面.在注册界面绑定学校,设置手机号和密码即可.在菜单栏点 ...
- 智慧校园系统平台实现校内导航资产管线一体化管理
构建智慧校园系统平台是国家和大专院校共同倡议的校园信息化建设方向,是运用物联网技术搭建的一体化综合平台,基于各种应用服务系统,把学校的教务.办公.教学.学习.管理.资产.校园安全.安防.消防等各个环节 ...
- 校园二手平台的开发和利用
传送门:软件工程(2018)团体第1次作业 一. 题目要求 建立团队博客,可以指定一名同学的博客,今后所有的作业都发布在该同学的博客上(建议使用队长的博客) 团队各成员集体讨论,在我们讲过的团队类型中 ...
- gis环境设置在哪_三维GIS平台的可视化应用 (下)
上一篇主要对三维GIS的基础数据和三维模型进行了一点说明,本篇将接着聊剩下的部分,主要是三维GIS平台能够支持什么样的场景展示,并来对平台的应用进行一些介绍. 没看过上篇的朋友可以先了解一下再看本篇: ...
- osg 三维gis开发_三维GIS平台的可视化应用 (下)
上一篇主要对三维GIS的基础数据和三维模型进行了一点说明,本篇将接着聊剩下的部分,主要是三维GIS平台能够支持什么样的场景展示,并来对平台的应用进行一些介绍. 没看过上篇的朋友可以先了解一下再看本篇: ...
- 基于JAVA+SpringMVC+Mybatis+MYSQL的大学生校园兼职平台
项目功能: 本系统是一个大学生校园兼职平台,主要用户是商家.学生.管理员.商家可以发布兼职信息,发布后,管理员进入后台确认信息是否有效,并且审核该兼职信息.学生登录平台后,可以查看兼职信息,并且,可以 ...
- geoserver三维_集团公司自主研发三维GIS平台产品——GeniusWorld 2.0 C版本发布
正元三维GIS平台产品(GeniusWorld)是公司独立自主开发的软件产品,提供地上地下全空间一体化的三维地理信息服务完整解决方案,可根据用户需求实现个性化定制.2019年6月30日全新研发的三维G ...
- 校园综合平台-微信小程序版(整整两个月暑假的成果啊 (•ิ_•ิ))
前言 学习了一段时间的微信小程序,开始都是做零零散散的小项目,暑假借着晚上有的一点时间,决定自己写一个校园综合平台,包含二手市场.表白墙.音乐.文章.动态等一些功能,一方面可以锻炼自己的编程能力,一方 ...
- 基于微信小程序云开发的校园类平台
这期给大家介绍一个我压箱底的项目,一个集二手市场.兼职发布.失物招领.代取快递等功能为一身的校园类平台. 前端使用ColorUI,后端使用微信小程序云开发. 现在已经上线发布,并且长期运营维护. 大家 ...
最新文章
- MySQL DATE_FORMAT() 函数
- 关于Ajax 错误:'sys'未定义解决方法.
- 计算机学院大学生程序设计竞赛(2015’11)1007 油菜花王国
- 漫步最优化二十——下降函数
- 掌握SpringAOP
- Tensorflow2.0.0版本和Keras2.4.3不兼容
- c语言实现双拼算法,【连载】(开始学习C语言的指针)——乐创DIY C语言讲义——6.1节...
- 自定义/修改微信二维码样式
- 微信支付 商户号该产品权限未开通,请前往商户平台
- 湖北二本大学计算机排名,2017年二本大学排名及分数线(湖北省)
- java形参和实参的三种传递方式(值传递,地址传递,引用传递)
- Unity 3D中的射线与碰撞检测
- 数据结构实验一_图书馆信息管理系统
- Linux没有默认设置root密码
- java实现pdf加水印
- 设计一个函数把两个数字相加。不得使用 + 或者其他算术运算符
- 24个好用到爆的Python实用技巧
- NVIDIA Tesla® K80 加速 数字全息实时重建
- JavaScript学习笔记(四)(DOM)
- pycharm里的HTML添加背景,pycharm怎么改变背景颜色-pycharm设置背景颜色的方法
热门文章
- 电脑生成siri语音_Siri for Mac:苹果电脑也有语音助手
- python query方法_Pandas dataframe.query方法语法
- java反射 虚拟机优化_面试官问我:Java反射是什么?我回答竟然不上来......
- java 计算器类图_多态计算器(封装、继承、多态、简单工厂)
- android 開發人員模式,Android
- 嵌入式linux添加环境变量,Linux环境变量
- linux更新函数,linux系统不同对象升级方法详细介绍
- 香港计算机课程,香港计算机科学专业学什么?开设了哪些课程
- 判断是否有小数_一线老师笔记:数学判断题拿高分的技巧
- python解放二次开发_[转载]Python二次开发程序详解