Posts Tagged ‘arcgis’

风场的简单绘制

台风风场数据一般包括X、Y、U和V,分别表示经度、纬度、东西方向速度和南北方向速度。简单的绘制,可以在一个GraphicsLayer中根据这几个属性值绘制箭头。开始我想的是自己动态生成各种Symbol,但现在还没法实现。现在用的方法的主要思路是根据X和Y确定箭头的末端位置p1,通过U和V确定箭头的大小(为了在地图上可见,可以乘以一个常数来放大)length,并且根据|V/U|的反正切值算出箭头与东西方向的夹角theta,这样就能根据length和theta计算箭头的顶点位置p2。取length/8(取多少自己感觉吧)为箭头两翼的长度h,并设箭头两翼的夹角为pi/3(还是感觉),那箭头一翼与箭身的夹角就是pi/6。这样就能根据p2、h、theta和pi/6,计算出箭头的左右两翼末端的坐标pL和pR。根据箭头的不同朝向,计算具体的参数值。

具体代码如下(Vector类中就包含了四个属性XYUV):


        private void displayCurrent(List<vector> vectors)
        {
            var wm = new SpatialReference(3857);
            foreach (var vector in vectors)
            {
                var length = Math.Sqrt(vector.U * vector.U + vector.V * vector.V) * 5000;
                var theta = Math.Atan(Math.Abs(vector.V / vector.U));
                var p1 =
                    (MapPoint)_webMercator.FromGeographic(new MapPoint(vector.X, vector.Y, new SpatialReference(4326)));
                var h = length / 8;

                double alphaL, alphaR;
                MapPoint p2 = null;
                MapPoint pR = null;
                MapPoint pL = null;
                if (vector.U > 0 && vector.V > 0)
                {
                    p2 = new MapPoint(p1.X + length * Math.Cos(theta), p1.Y + length * Math.Sin(theta), wm);
                    alphaR = Math.PI / 2 - theta - Math.PI / 6;
                    alphaL = theta - Math.PI / 6;
                    pR = new MapPoint(p2.X - h * Math.Sin(alphaR), p2.Y - h * Math.Cos(alphaR), wm);
                    pL = new MapPoint(p2.X - h * Math.Cos(alphaL), p2.Y - h * Math.Sin(alphaL), wm);
                }
                else if (vector.U > 0 && vector.V < 0)
                {
                    p2 = new MapPoint(p1.X + length * Math.Cos(theta), p1.Y - length * Math.Sin(theta), wm);
                    alphaR = theta - Math.PI / 6;
                    alphaL = Math.PI / 2 - theta - Math.PI / 6;
                    pR = new MapPoint(p2.X - h * Math.Cos(alphaR), p2.Y + h * Math.Sin(alphaR), wm);
                    pL = new MapPoint(p2.X - h * Math.Sin(alphaL), p2.Y + h * Math.Cos(alphaL), wm);
                }
                else if (vector.U < 0 && vector.V > 0)
                {
                    p2 = new MapPoint(p1.X - length * Math.Cos(theta), p1.Y + length * Math.Sin(theta), wm);
                    alphaR = theta - Math.PI / 6;
                    alphaL = Math.PI / 2 - theta - Math.PI / 6;
                    pR = new MapPoint(p2.X + h * Math.Cos(alphaR), p2.Y - h * Math.Sin(alphaR), wm);
                    pL = new MapPoint(p2.X + h * Math.Sin(alphaL), p2.Y - h * Math.Cos(alphaL), wm);
                }
                else if (vector.U < 0 && vector.V < 0)
                {
                    p2 = new MapPoint(p1.X - length * Math.Cos(theta), p1.Y - length * Math.Sin(theta), wm);
                    alphaR = Math.PI / 2 - theta - Math.PI / 6;
                    alphaL = theta - Math.PI / 6;
                    pR = new MapPoint(p2.X + h * Math.Sin(alphaR), p2.Y + h * Math.Cos(alphaR), wm);
                    pL = new MapPoint(p2.X + h * Math.Cos(alphaL), p2.Y + h * Math.Sin(alphaL), wm);
                }

                var arrow = new ESRI.ArcGIS.Client.Geometry.Polyline();
                var path1 = new ESRI.ArcGIS.Client.Geometry.PointCollection { p1, p2 };
                arrow.Paths.Add(path1);
                var path2 = new ESRI.ArcGIS.Client.Geometry.PointCollection { pL, p2, pR };
                arrow.Paths.Add(path2);

                _currentLayer.Graphics.Add(new Graphic
                {
                    Geometry = arrow,
                    Symbol = new SimpleLineSymbol(Colors.Black, 1),
                });
            }
        }

效果如下:

做这个是因为师姐毕业论文中要用,而且自己以后肯定也会用到,毕竟都是一个方向的。参考以前毕业师姐写过的代码,完善了一下,就用ArcGIS API for Silverlight做了个例子。

杭州实时公交–以B1线为例

=============

更新:

自从我写了这个以后,B1线的实时数据貌似就没有正常过。当初选择B1线无非是因为他是快速公交,比较出名,而且以前坐的也比较多点。既然B1线不行,那就换个别的了。现在用的是194路坐例子,站点是蒋村公交中心站,也就是地图上最上方的那个。反正能说明问题就行了吧。

=============

以前在杭州等车的时候见过路牌上有公交车的到站信息,虽然感觉有时候不太准但还是比较新颖的;后来在网上看到有人做手机端的实时公交应用,但我那时对Web开发还啥都不懂,搞不清楚怎么回事,当然现在也只是知道一点点;再后来又看到些Live、Realtime的应用,感觉到公交也是一个很好的实时例子;去年末写了个公交换乘算法,处理了一些南京市的公交数据,对公交应用也略有了解;上个月初,突然对(www.hzbus.cn)开始感兴趣,找到了它的服务调用地址,顿时以前的一些想法开始脑中翻滚,就开始动手操作了。

最近这个月事情好多,转眼间就过去了,我只是断断续续再做这个事情。碰到的问题也相当相当多,比如服务给的坐标都是经过偏移的,这种致命打击完全让我失去了做一个完整应用的动力,我;再比如典型的跨域问题,Silverlight对第三方的服务有什么好的解决办法吗?我用的是YQL来做的;还有就是自己的能力不足,对Web开发、Silverlight以及ArcGIS API都只是停留在入门的水平,没有一个完整的项目来驱动,很难更深入的学习了。

简单说说这个例子的思路:地图调的是arcgisonline.cn上的服务,很喜欢gray风格,特别是做Mashup的时候,能很鲜明地突出专题信息;公交线路、站点和车辆实时位置当然是调用前面提到网站中的服务了,但为了实现跨域访问,经过了YQL的一层包装;解析抓取到的数据,都作为简单的Graphic添加到相应图层中;对于实时位置,显然要通过计时器,每隔几秒去抓一次数据,更新位置的。

总的来说,做的比较简单,与我开始的雄心壮志相比不知差了几条街额。下面是这个例子:

这个是杭州B1线,下沙->黄龙方向,终点站黄龙公交中心站(最西边那个站)的实时公交情况。也就是说,假设你在黄龙公交中心站,能看到向你开过来最近的3辆B1车的实时位置(按理应该是这样吧,但实际上服务给的数据还是有出入的)。表格中是三辆车的数据,包括车辆编号,位置和速度。B1的工作时间是到晚上10点,10点以后你肯定看不到公交车啦。

最后,希望有更多的单位出来共享数据,提供友好的API,特别是带GeoLocation的。我想只有这样,我们提的那些智慧城市之类的口号才有实现的可能吧。

用ArcGIS计算测地线

你一定见过Facebook那张著名的友邻图:

图中两个地点之间的连线不是直线,而是测地线(Geodesic),或者说大圆路径、航线等等。其实就是球体上两点之间最短路径投影后的表示。用测地线做图需要有比较多的数据,这样可以表现的比较“繁忙”。而且地理上必须是大范围的,不然看上去还是直线,就缺少了曲线的美感。

在ArcGIS中,也有计算测地线的工具,XY To Line

它需要一张包含起始点地理坐标的表,就能输出两点之间的测地线了。使用起来很简单,当然真要自己算应该比较麻烦的。

下面举个不恰当的例子:美驻华使领馆与省会城市之间的距离关系

美国在华有7个使领馆:北京、沈阳、上海、武汉、成都、广州和香港,不考虑香港。

大陆有31个省会城市,能享受“休假式治疗”的起码得是地方大员,处级干部就不考虑了,当然也不包括港澳台。

数据来自国家基础地理信息中心。

使邻馆是点数据,省会城市也是点数据,那么只需计算点和点之间的距离关系就可以了。

具体步骤见代码:

简要说明下,首先为点数据添加坐标属性,之后计算两两之间的距离,然后为距离表连接起始点的坐标属性,最后根据距离表计算测地线。

结果如下(点击可看大图):

仅供参考。