Geospatial Thinking
-
GIS BLOGS(不断更新) - [置顶]
2009-11-21
Thinking in GIS
博主从事开发多年,曾工作于意大利ESRI,现工作于 IPI (Istituto Promozione Industriale。该博主要focus on OpenGIS.
michalisavraam.org blog
博主是华盛顿大学的一名研究生,该博会转一些有意思的spatial news,并给出一些comment -
SqlDataAdapter无法更新自增列的解决方案 - [C#]
2011-08-17
自己写SQL更新自增列很好办,只要update (xx,yy,zz)的时候不要把自增列写进去就可以了;
但是,我用的SqlDataAdapter,在table.addRow(row)的时候提示自增列不能为空;
想想也对,自增列确实在sql server里定义为不准为null;
怎么办呢???
解决办法也挺简单,设置tabel.Columns[0].AllowDBNull = true;就可以了,目的就是要告诉table,这一列可以为空,就可以插入啦
-
CSS笔记(一) - [Web Development]
2011-05-02
selector {property: value}
e.g. h1 {color:red; font-size:14px;}
p { color:rgb(255,0,0);}
h1,h2,h3,h4,h5,h6{
color: green;
}
派生选择器:
li strong{
font-style: italic;
font-weight: normal;
}
id选择器:
#red{color:red;}
#green{color:green;}
#sidebar p{
font-style: italic;
text-align: right;
margin-top: 0.5em;
}
CSS类选择器.center{text-align: center}
CSS属性选择器
[title]{ color:red; }
input[type="text"] { width:150px; display:block; margin-bottom:10px; background-color:yellow; font-family: Verdana, Arial; } input[type="button"] { width:120px; margin-left:35px; display:block; font-family: Verdana, Arial; }
外部CSS
<linkrel="stylesheet" type="text/css" href="mystyle.css" />
内部CSS
<style type="text/css">hr {color: sienna;} p {margin-left: 20px;} body {background-image: url("images/back40.gif");}</style>
-
Javascript备忘(一) - [Javascript]
2011-04-27
Javascript是一种解释型的编程语言 ,而Java、C++是编译型的。
Javascript是一种弱类型语言 ,而Java、C++是强类型的。
- Javascript的注释://, /* ... */
- Javascript变量的定义:var age; var age=33;
- JS变量区分大小写
- var mod = 'happy'; var mod = "happy"; var mood="don't ask"; var mood = 'don\'t ask';
- var beatles = Array(); var beatles = Array(4);
- var beatles = Array("John","Paul","George","Ringo");
- var lennon = Array(); lennon["name"] = "John"; lennon["year"]=1940;
条件语句和循环语句
- if(condition) {statements;} else {statements;}
- ==, !=, &&, ||, !
- while(condition){statements;} do{statements;} while(condition);
- for(var count =1; count<11; count++){alert(count);}
函数
- function name(arguments) {statements;}
DOM
- 元素节点(element mode);文本节点(text node);属性节点(attribute node);
- getElementById(); typeof(xx);
- getElementByTagName("li");返回的是一个数组
- getElementByTagName("*");返回有多少子节点
- getAttribute("title");返回title的属性值
- shopping.setAttribute("title","a list of goods")
- innerHTML
- var para= document.createElement("p"); parent.appendChild(child);
- var txt = document.createTextNode("Hello world");
- parentElement.insertBefore(newElement,targetElement)
- Javascript最重要的在于JS、HTML、CSS的分离
- 对浏览器的名称和版本号进行嗅探的方法很难做到面面俱到,而且往往会导致非常复杂难解的代码
-
Python3学习笔记(三) - [Python]
2011-01-12
- Python不用{}来表明代码结构,而用indentation
- #来表明注释
- 变量名是大小写敏感的
- Numpy www.scipy.org
- import cmath #用来做复数的计算
- name = input("Name? ")
- Python推荐的书写方式例子:包名称sys,函数名foo、my_func,变量名my_var,类名MyClass,缩进4个空格不要用TAB,比较if my_var不要和True or False对比
Lists, tuples and sets
- 如果需要用大量的数学计算,最好还是用Numpy
- x[:0] = [-1,0] #将数据添加到List的最前方
- x[1:-1] = [] #清除数据
- list的append和extend方法类似,不同之处在于extend可以将另一个list中的每一个元素加进来
- list可以自定义sort方法,比如按照单词的长度来sort,只需要修改sort方法的key参数即可
- 自定义sort(修改reverse参数)比起先sort再revert要慢
- sorted()可以判断iterable是否已经排序好
- import copy; copy.deepcopy可以防止两个object更改同一个值
- tuple本身是不可以改变的,但是如果tuple里如果有list或者dict则可以
- 只有一个元素的tuple一定记得要加",",比如(7,);否则它将和(7)想混淆
- frozenset #不可变的set
-
Python3学习笔记(二) - [Python]
2011-01-10
字符串:
- 字符串可以用' '," ",''' ''',""" """四种方式来定义
- " "里可以用' ',' '里可以用" ",其他时候要用\来转义
- 字符串也是不可改变的
- 字符串适用操作符(in,+,*),内建函数(len,max,min),index和切片
- import re 可以使用正则表达式
- print("the value of %s is: %.2f" %("e",e))
字典:
- x = {1:"None", 2:"two"}
- x["first"] = "one"
- x.get(1,"not available")
- x[keys] = values
- key必须是Integer,String或者Tuple。List不行
Set:
- x=set([1,2,3,1,3,5])
文件对象:
f = open("myfile","w")
f.write("First line\n")
f.close()
f = open("myfile","r")
line1 = f.readline()
import os
print(os.getcwd())
控制流程:
if x<5 :
y = -1
z = 5
elif x>5:
y = 1
z = 11
else:
y = 0
z = 10while xxxxx:
do something.for x in item_list:
do sth.函数
def funct4(x, y=1, z=1, **dictionary):
print(x,y,z,dictionary)
funct4(1,2,m=5,n=9,z=3)import imp
imp.reload(wo) #重新载入类库 -
Python3学习笔记(一) - [Python]
2011-01-09
Part1 开篇
Python is easy to use
- 变量可以被赋值为任何类型,而list可以包括不同的类型
- Python高度抽象(下载页面只需要2-3行代码)
- 适合快速开发
交换值:var2, var1 = var1, var2
It is easy to extend Python with modules written in C or C++
Part2 安装
IDE中Alt+/ 自动提示
Ctrl+C :KeyboardInterrupt
print("Hello Python3.1")
经常会用到的有用的函数
- help()函数
- dir()函数
Part3 快速预览
整型:
- Numbers: python的4种数字类型包括:整型,浮点型,复数类型,布尔型
- "/"是浮点除(Python3.x新引入) ,"//"是整除
- **是幂指数
- integers是没有大小范围的
- 内建函数比如round()、import math
- 布尔型中False、True注意要大写
列表(List):
- 列表可以包含具有不同类型的elements
- 列表的切片功能非常强大
- x[a,b] means 从x[a]到x[b]间的元素,但不包括x[b]
- 列表中有许多内建函数可以用(len,max,min),一些操作符(in,+,*),list自己的函数(append,count,extend,index,insert,pop,remove,reverse,sort)
- "+"只适用于List之间的操作,而"*"使得List重复自己。如何让List中的每一个元素乘以一个数
元组(Tuple):
- 元组一旦创建就不可以被改变!!!
- 元组可以和列表进行互相转换:list(),tuple()
预知后事如何,请听下回分解:3.2.4字符串
PS:今晚学习扎克伯格用来写blog,很有意思啊
-
Friday Geonews 0109 - [News Roundup]
2011-01-09
James Fee
http://www.spatiallyadjusted.com/2010/12/13/wait-what-file-geodatabase-api-is-on-its-way/
· 访问 File Geodatabase API 可以不经过 AO
· 只支持 ArcGIS 10 以后的 file geodatabases , 9.x 系列不支持
· 一些属性例如 annotation, networks, topologies 仍然需要 AO 支持
· API 是基于 C++ 的库
· 只能在 Windows 平台使用
· 栅格暂时不支持
· 矢量查询暂时只局限于 envelope intersects
·
参考文章 http://blogs.esri.com/Dev/blogs/geodatabase/archive/2010/12/13/File-Geodatabase-API-details.aspx
Python 在 ArcGIS10 中的新闻
http://www.spatiallyadjusted.com/2011/01/03/2011-the-year-python-takes-over-gis/
New Bing Tile Layer Type in OpenLayers
Openlayer 可以直接访问 Bing Map 的 Tiles.
Fuzzy Tolerance
Kataspace is a browser based virtual world built with HTML5 and WebGL
Google Maps 5.0 Is Awesome
-
SharpMap功能拓展之空间分析功能 - [SharpMap]
2010-08-02
来气象局这边实习近半个月,主要工作内容为GWASS系统编写空间分析功能。GWASS系统是在开源类库基础上建立起来的服务系统,基于的开源类库包括WorldWind、SharpMap、Proj.4等等。SharpMap主要被用来读取矢量格式的文件,如果要用到空间分析,第一个想到的就是JTS的.NET版本NetTopologySuite(NTS)。
NetTopologySuite是著名的JTS Topology Suite的C#/.net版本,简称NTS,JTSTopology Suite为一个OpenGIS标准的GIS分析、操作类库。NTS项目的目的是提供一个基于.net,快速、稳定的GIS解决方案,以应用于所有.net平台,包括各类嵌入式设备。
在SharpMap中使用NetTopologySuite的简单例子可以参照Mars写的这篇文章。虽然SharpMap和NTS都是基于OGC的简单要素规范,不过NTS为了可以进行方便的空间分析,Geometry的定义与SharpMap的并不是完全相同,因此在进行空间分析操作的时候切记要将SharpMap的Geometry转换到NTS的Geometry上来。
GisSharpBlog.NetTopologySuite.Geometries.Geometry geo = GeometryConverter.ToNTSGeometry(geometry, geometryFactory);
NTS的Geometry提供了许多空间关系的判断操作,比如Disjoint、Touches、Intersects、Crosses、Within、Contains、Overlaps、Covers、CoveredBy、Relate等,还有一些是空间叠置分析。目前,NTS只提供四种空间叠置分析,分别是Intersection、Union、Difference和SymDifference。总体上说来,这四种操作基本满足一般的空间分析需求了。
除了Overlap以外,NTS还提供Buffer、Distance、Linemerge、Polygonize、Predicate、Relate等分析功能。
下面是我写的一个查询某图层中与某个Geometry相交的例子:
public void ExecuteClipQuery(GisSharpBlog.NetTopologySuite.Geometries.Geometry geometry, FeatureDataSet ds)
{
// GisSharpBlog.NetTopologySuite.Geometries.Geometry geometry = GeometryConverter.ToNTSGeometry(geom, geometryFactory);
SharpMap.Data.FeatureDataTable dataTable = CreateFeatureDataTable("area");
foreach (GisSharpBlog.NetTopologySuite.Features.Feature feature in features)
if (feature.Geometry.Intersects(geometry))
{
GisSharpBlog.NetTopologySuite.Geometries.Geometry intersectGeo;
if(geometry.Contains(feature.Geometry))
intersectGeo = feature.Geometry;
else
intersectGeo= feature.Geometry.Intersection(geometry);
GisSharpBlog.NetTopologySuite.Features.Feature newFeature = new GisSharpBlog.NetTopologySuite.Features.Feature(intersectGeo, feature.Attributes);
FeatureDataRow dataRow = CreateNewRowBySHG(dataTable, newFeature);
dataRow["area"] = intersectGeo.Area;
dataTable.AddRow(dataRow);
}
ds.Tables.Add(dataTable);
} -
AE中HRESULT:0x80040215异常的问题 - [ArcGIS Engine]
2010-05-04
在使用 ITopologicalOperator求交集等操作的时候,有时会出现“ HRESULT:0x80040215”这个异常,原来是空间参考不一样所致。因此只要SpatialReference 属性设为同一空间参考就不会出现“ HRESULT:0x80040215”异常。
-
应用机载激光雷达分析冰岛火山灰在大气层中的变化 - [Quick Note]
2010-04-19
转载请注明出处:Geospatial Thinking
英国国家气象服务中心——Met最近在使用多普勒激光雷达来模拟英国 上空的火山灰分布。研究结果表明,现在火山灰的数量呈稳步下降趋势,并且已逐步进入对流层,所以我们现在可以用肉眼看到火山灰对我们造成的影响。
从下图可以看出,温度随着对流层的高度的变化而变化,图中的颜色代表在那个时间点大气中不同的悬浮颗粒。图中左边的纵轴代表在观测点上方的高度(此图中为贝德福德郡的Cardington)。水平轴代表的时间轴,从2010-4-16日的早上8点到中午12点30。 火山灰在此图中用黄色偏蓝的线表示,大概从3000m到1400m左右,可以明显看出一个下降的趋势。

更清楚的版本:

原文地址:http://www.metoffice.gov.uk/corporate/pressoffice/2010/volcano/lidar/
-
ArcGIS Server之闪烁要素 - [ArcGIS Server]
2010-03-18
之前一篇曾提到高亮查询要素,这篇来讲讲怎么闪烁要素。
桌面开发中,AE提供了很方便的FlashShape的方法,但在web方法中却没有这样的实现,因此需要我们自己定制代码实现要素的闪烁。
在web中闪烁要素的方法有很多。有人说可以在服务器端获得坐标,传到客户端后将gif显示在客户端的div中实现闪烁。这种方法有两个弊端,一是这种方法比较适合点闪烁,二是如果移动地图后div需要重新计算位置,总体来说比较麻烦。也有人说在前台用js在客户端不停显示/隐藏graphiclayer实现闪烁;还有人说服务器端将坐标传回前台,结合adf js自己操纵graphics。个人上感觉第一种方法弊端太大,第三种方法需要传送数据且自己要写的代码太多,因此第二种方法更加方便。
所以根据第二种方法的思想,我在服务器端定义了FlashFeatures函数。这个函数新建了一个带有javascript函数的callbackResult,想要闪烁的时候只需要传入想闪烁图层的名字即可,不需要考虑闪烁要素的类型(点、线、面)。另外,这个函数最关键的部分在于setTimeout的用法,500*(j+1)设置了不同的刷新时间,这个idea还要感谢server群的alex xu,不然我就要开始考虑递归了...
void FlashFeatures(Map map,string layerName)
{
string scriptBlock = @"
function getlayer()
{{
map = $find(""Map1"");
var layers = map.get_layers();
var count = layers.get_layerCount();
for(var i=0;i<count;i++)
{{
var layer = layers.get_layer(i);
var name = layer.get_name();
if(name=='{0}')
{{
for(var j=0;j<5;j++)
{{
setTimeout(function(){{
layer.set_visible(!layer.get_visible());
map.refreshLayer(layer);
}},500*(j+1));
}}
layer.set_visible(false);
map.refreshLayer(layer);
}}
}}
}}
getlayer();";
scriptBlock = string.Format(scriptBlock, layerName);
CallbackResult cr = CallbackResult.CreateJavaScript(scriptBlock);
map.CallbackResults.Add(cr);
}PS:ADF javascript库还是蛮有用的,以后要多留意一些
-
基于Partial Postback制作饼状专题图过程中碰到的种种问题 - [ArcGIS Server]
2010-03-08
寒假之前基于Callback做过一个ResourceList、LayerList、FieldList三级联动的代码,后来觉得callback做这个方案有点罗嗦,就考虑能不能尝试下不太熟悉的partial postback,做一个可以定制字段的专题图功能。
server 中传统专题图的实现,比如唯一值专题图、分类专题图都有现成的方法。稍微高级一点的ChartRender和BarRender则需要在后台用AO来渲 染,然后动态改变资源。前人在这方面研究了很多,我主要就借鉴了[url=viewthread.php?tid=19225& highlight=%D7%A8%CC%E2%CD%BC]这个帖子[/url]里的专题图的代码,以及 [url=viewthread.php?tid=43638&extra=&highlight=%D7%A8%CC%E2%CD %BC&page=2]这个帖子[/url]的sorth同志关于如何不重启服务达到清除专题图的思想。
做完上面的,饼状专题图 的功能就基本实现了。不过令人感到奇怪的是,TOC并没有跟着Map的刷新而改变图例,反倒是专题图功能应用后会出现TOC失灵的情况(无法控制图层的可 视)。当时使用的代码是Toc.Refresh()以及将Toc的CallbackResult拷贝给 Map:map.CopyFrom(toc.CallbackResults)。在调试过程中发现toc返回的callbackresult数量为0,字 符串为null,并且跳出{Script control 'Toc1' is not a registered script control.Script controls must be registered using RegisterScriptControl() beforecallingRegisterScriptDescriptors()}的异常。google了一下,发现有人用stringwriter 自己来渲染TOC(因为TOC本来就是基于treeviewlist拓展的)。换了思路后发现还是会出现以下异常:{"类型“HiddenField”的 控件“TocPanel_Toc1_hfSelectedNode”必须放在具有 runat=server的窗体标记内。"}。无奈,只能去arcgis serverforum上搜类似的问题。在这个过程中发现TOC问题多多,唉...不过还是找到了这个问题的解决办法——打arcgis93 SP1补丁。
引用下ESRI论坛上某官方回答
“From ESRI:
"This is a known defect logged as NIM035636: CallingRefresh on a TreeViewPlus control returns an error stating that it isnot a registered script control. Unfortunately, there is no workaroundat this point.”
“A bug has been logged for the issue. And it's scheduled to be fixed in 9.3 SP1. ”
后来就跑去打了SP1补丁,基本就没问题了。sigh~~~~人生中碰到的第一个bug。
这次关于TOC刷新的另一个体会是有时候TOC刷新并不需要显示的将CallbackResult拷贝给Map,这在前面的AJAX系列文章里也有提到,因为Toc控件会自动的将callbackresult传送给Map。
-
LiDAR点云生成DSM新算法 - [LiDAR]
2010-02-12
之前的LiDAR点云生成DSM算法思路:
1.生成与参考影像相同矩阵大小、相同分辨率的矢量网格(Grid)
2.将lidar点和Grid存入SDE中进行空间索引,然后空间叠置分析,计算网格高程值。
3.以矢量网格的高程值作为像元值,将矢量网格转化成DSM栅格影像
新的LiDAR点云生成DSM算法思路
1.新建与参考影像相同矩阵大小、相同分辨率、相同投影的栅格影像(IMG)
2.新建和参考影像相同大小的矩阵(Array),矩阵元素为List,存储落入cell的点高程坐标
3.读取参考影像的四个角点坐标(xMin,xMax,yMin,yMax),计算分辨率(xMax-xMin)/cols
4.将lidar点存入SDE中进行空间索引,遍历所有点,(Point.x-minX)/resolution,(Point.y-minY)/resolution得到所在矩阵位置(col,row),将高程信息加入对应栅格的List
5.对矩阵中的List进行处理(DSM生成算法)
6.将矩阵高程值赋值给DSM栅格影像,并保存
可以看出,与之前判断矢量点与多边形不同的是,新算法直接判断lidar点所在栅格的位置。这样的话,每个点只要判断一次,算法的效率为O(n)。另外,FeatureCursor的NextFeature方法非常适合读取只读数据,速度比起直接的featureClass的getFeature方法要快很多,也在一定程度上提高了算法效率。
值得注意的是,CreateRasterDataset方法的IPoint参数为图像坐下角的x,y坐标,而IRasterEdit在写入数据的时候是从左上角开始写入。所以,如果还是以i,j来写入,会倒置图像关于水平方向对称,因此在保存数据的时候需要倒过来写入,即pixelArray.SetValue(value, i, rows - j - 1).
过几天再将LAS2DSM和TXT2DSM搞出来。
-
PostGIS新数据类型——地理数据类型 - [PostGIS]
2010-02-08
1.地理数据类型介绍
地理数据类型主要是用来提供以地理坐标(我们常说的大地坐标,或者经纬度)表示的空间要素的支持。地理坐标属于球面坐标,以度(degree)来表示。
PostGIS几何数据类型的基础是一个平面,平面上两点之间的最短距离是一条直线。因此,我们在计算几何图形的面积、距离、长度、交集等操作时可以使用笛卡尔数学计算公式(Cartesian mathematics)和直线向量(straight line vectors)。
相反,PostGIS地理数据类型的基础是一个球体。球体上两点之间的最短距离是大圆圆弧(great circle arc)。这意味着在进行相同的地理计算时需要更复杂的数学计算公式。如果要结果更加精确,则必须考虑我们真实世界的球体形状,这样将使计算变得更加复杂。因此,基于地理数据类型的功能函数要大大少于基于几何数据类型的功能函数。但是随着PostGIS版本的不断更新,越来越多基于球面的算法将会加入进来,地理数据类型的功能也会越来越强大。
现在PostGIS地理数据类型的一个弱势在于它还只支持WGS84(SRID:4326)的经纬度坐标。GEOS的所有功能函数都暂时还不支持这种新数据类型。
2.地理数据类型基础
PostGIS地理数据类型现在仅支持最简单的要素,包括点(Point),线(LineString),面(Polygon),多点(MultiPoint),多线(MultiLineString),多面(MultiPolygon)以及混合数据类型(GeometryCollection)。
创建带有二维点数据的表可以如下例所示:
CREATE TABLE global_points(
id serial PRIMARY KEY,
name VARCHAR(64),
location geography(POINT, 4326)
);
上例中,location字段属于地理数据类型,它具有两个可选的限制参数:前一个参数限制该字段存储图形的类型及维数;后一个SRID限制了图形的坐标参考。在现在的版本中,只有SRID为4326的坐标可以被支持。如果SRID没有被指定,默认将会以0(undefined spheroid)来替代,但所有的计算还是会基于WGS84。当然,在未来的版本中,其他SRID也会被陆续支持。
另一点需要注意的是,与之前版本中几何数据的创建不同,新的地理数据字段不需要注册在geometry_columns里,而是在一个新的视图里注册,称为geography_columns。因此,不需要显示的调用AddGeometryCollumn之类的功能函数。
一旦带有地理数据字段的表建好,就可以像下面的例子一样往表里插入数据:
INSERT INTO global_points (name, location)
VALUES ('Town', ST_GeographyFromText('SRID=4326; POINT (-110 30)'));
建立索引和几何数据类型类似。
CREATE INDEX global_points_gis ON global_points USING GIST(location);
查询与距离量算将以米为单位:
SELECT name FROM global_points WHERE ST_DWithin(location, ST_GeographyFromText('SRID=4326;POINT (-110 29)'), 1000000);
你可以通过查询从西雅图飞到伦敦的航线距离雷克雅未克的最短距离来体会地理数据类型的强大。
SELECT ST_Distance('LINESTRING(-122.33 47.606, 0.0 51.5)'::geography, 'POINT(-21.96 64.15)'::geography);
3.地理数据类型和几何数据类型的选择
地理数据类型使得我们可以将以经纬度表示的数据进行存储,但需要耗费一定的代价:基于该类型的功能函数比较少;这些函数也要花费更多的CPU时间来计算。
选用地理数据类型还是几何数据类型取决于使用者所研究的区域。你的研究区是遍布全球或比较大的区域,还是一个国家,一个城市,甚至于一个乡村。如果你的研究区只是一个很小的区域,最好的选择就是挑选合适的投影并基于几何数据类型来计算。如果你的研究区遍布全球或是一个相当大的区域,你就应该将数据以经纬度存储,选用地理数据类型来存储,不需要考虑复杂的投影细节。如果你对投影不是很了解,你也不想去学习它们,那么建议你使用地理数据类型。简单的导入你的数据就可以达到你的目的。
-
PostGIS 1.5.0 Released - [Quick Note]
2010-02-07
上周四,PostGIS发布了最新版本1.5.0。这个版本有很多有意思的功能,最引人注目的是一种新数据类型的加入——地理数据类型(Geography Type)。这种数据类型直接支持我们常用的大地坐标(geodetic coordinates),即经纬度(lat/lon coordinates)。
在PostGIS之前的版本中当然也是可以导入与计算经纬度信息的。但这些计算方法忽略了一个事实——大地坐标是有角度的(angular units),不是无角度的笛卡尔坐标(Cartesian units)。因此,横跨poles of datelines的物体并不能合理的定位,计算面积、长度、距离,这些返回的结果是以度为单位而不是以米为单位的。
在PostGIS 1.5中,新的地理数据类型是一种100%基于球面的数据类型,它可以合理的全球定位,并返回以米为单位的更加精确的结果。
我们期望这种数据类型可以让用户更简单方便的将他们的数据存储在PostGIS中,而不必去学习投影或者坐标系统等专业知识。
本次版本还有其他重要功能,如下:
The 1.5.0 release of PostGIS is now available. This is a major release adding a significant number of new features including:
- New “geography” type for managing geodetic (lat/lon) data
- Performance-enhanced distance calculations
- GML and KML format readers
- Improved shape loading GUI
- And more!
RELEASE NOTES
Important Changes- =~ operator now indicates bounding box equality, not feature equality
- GEOS 3.1 is now the minimum accepted version of GEOS
- GEOS 3.2 is needed if you want to use enhanced buffering features and ST_HausdorffDistance
- GEOS, LibXML2, and Proj4 are now mandatory dependencies
- New Features
- Added Hausdorff distance calculations (#209) (Vincent Picavet)
- Added parameters argument to ST_Buffer operation to support one-sided buffering and other buffering styles (Sandro Santilli)
- Performance improvements to ST_Distance (Nicklas Avén)
- Addition of other Distance related visualization and analysis functions (Nicklas Avén)
- ST_ClosestPoint
- ST_DFullyWithin
- ST_LongestLine
- ST_MaxDistance
- ST_ShortestLine
- KML, GML input via ST_GeomFromGML and ST_GeomFromKML (Olivier Courtin)
- Extract homogeneous collection with ST_CollectionExtract (Paul Ramsey)
- Add measure values to existing linestring with ST_AddMeasure (Paul Ramsey)
- History table implementation in utils (George Silva)
- Win32 support and improvement of core shp2pgsql-gui (Mark Cave-Ayland)
- In place ‘make check’ support (Paul Ramsey)
- Geography type and supporting functions
- Spherical algorithms from Dave Skea
- Object/index implementation from Paul Ramsey
- Selectivitiy implementation from Mark Cave-Ayland
- Serializations (KML, GML, JSON) from Olivier Courtin
- ST_Area, ST_Distance, ST_DWithin, ST_GeogFromText, ST_GeogFromWKB, ST_Intersects, ST_Covers, ST_Buffer
- Documentation updates and improvements (Regina Obe, Kevin Neufeld)
- Testing and quality control (Regina Obe)
- PostGIS 1.5 support PostgreSQL 8.5 trunk (Guillaume Lelarge)
- Many, many other changes
-
NOKIA发布新OVI地图 将冲击导航产业 - [业内新闻]
2010-01-23
2007年10月,诺基亚以81亿美元收购数字导航公司Navteq,并逐渐在手机内置导航服务,在诺基亚手机的互联网服务中也包括导航业务。
1月21日下午,诺基亚全球同步发布了全新的Ovi手机导航地图和服务,并宣布Ovi地图将永久免费为用户提供服务。业内人士表示,此举将是Google宣布提供地图导航功能以后,又一将对GPS导航相关产业带来重要影响的事件。
此次发布的Ovi地图新版本支持离线定位、手机导航,包括所有驾驶和步行导航功能,提供74个国家46种语言的语音导航、10多个国家的交通信息以及180多个国家的详细地图。同时,Ovi地图支持在线与离线两种模式。
除此以外,最令我觉得可怕的是开发商可以开发基于OVI地图的应用。目前已经整合的应用包括国内三大应用服务商玩主、大麦票务和携程网,提供包括商旅、票务在内的更多增值服务,而且同样是全部免费的。Ovi俨然已经成为了一个炙手可热的平台。
诺基亚表示,在中国销售的E72、E52、5230、6730、X6和N97 mini均支持新版的Ovi地图。从今年3月份开始,新推出的有GPS功能的诺基亚智能手机将内置Ovi地图新版本,并预装当地国家的地图数据。其他 Symbian V3.2和V5.0系统手机用户则可登陆诺基亚网站免费下载。
期待Planet Spatial后面的跟踪评论,国外就喜欢这样,一有个事情就扎堆评论,其实也挺好的。在中国,连跳出来讲话的都没有,跳出来的也是暴民。
-
ArcGIS Server9.3 AJAX系列(四)之总结 - [ArcGIS Server]
2009-12-21
前面两篇文章我们介绍了ArcGIS Server93 AJAX的两种模式,分别是Client Callback和ASP.NET AJAX(也可以称为局部页面刷新,partial page rendering)。本篇主要将这两种方案做一个对比,比较两种方案的优缺点,探讨适用的情景。
Client Callback
随着ASP.NET 2.0的发布,微软为网络应用提供了一个简单、轻量、高效的AJAX解决方案,称为客户端回调(Client Callback)。这种解决方案仅凭一个接口(ICallbackEventHandler),一个客户端脚本管理类和一个Javascript文件 (WebForm.js)就可以管理客户端与服务器之间的异步传输。在运行时环境下,页面初始载入后,客户端回调页面时经历的页面周期与传统的同步传输有 些不同。如下图所示,页面经历了初始化和载入(initiate and load),但页面没有被渲染(render),取而代之的是服务器端的代码被调用,处理客户端的回调请求并返回一个值给客户端,客户端的 Javascript函数基于DOM和DHTML技术动态的更新网页内容。虽然客户端回调是一个轻量级的AJAX框架,但它也有一个很大的缺点:在客户端 回调时,开发者必须提供所有客户端服务器端和客户端渲染页面内容的代码,并且管理客户端与服务器之间的异步通信,这无疑加重了开发人员的负担,也在一定程 度上促成了ASP.NET AJAX的推出。
ASP.NET AJAX
为了提供一个更全面的AJAX解决方案,微软于2007年初提出了ASP.NET AJAX。该方案在服务器端提供一系列AJAX控件(ScriptManager,UpdatePanel等)和API用于管理异步通信,同时通过客户端 的Microsoft AJAX Library动态更新页面内容,这就使得开发人员甚至不用编写任何客户端脚本就可以实现异步刷新。与Client Callback不同的是,局部页面回发经历了与同步传输一样的页面生命周期,但只有页面上一些特定的区域和控件得到刷新,所以又称为局部页面刷新 (partial page rendering)。
事实上,ASP.NET AJAX依赖于拦截机制(interceptor pattern)来处理部分回发。在初始化后,ASP.NET AJAX Javascript Library在客户端立即添加一系列客户端事件处理器(event handler)用来截获会引起整体页面回发的请求。这些事件处理器仅截获注册控件发起的回发请求,并转化成部分回发请求,在服务器响应后处理接收到的内 容并动态更新页面。

总的来讲,两个技术各有优缺点。ASP.NET AJAX框架的出现不是为了取代客户端回调(Client Callback),而是微软给开发者提供一个更为便捷的开发环境。
客户端回调(Client Callback)
优点在于回调时发送请求和返回结果的字符串都由开发者自定义和解析,更为灵活和轻便。当然,ArcGIS Server中提供了CallbackResult和processCallbackResult函数,更加方面了开发者。另外,客户端整个页面的生命周 期比传统Postback短(无论是同步或者异步),更为高效。
缺点是需要开发者编写客户端脚本和服务器代码。
ASP.NET AJAX (partial page postback)
优点在于实现方便,拖动控件便可以实现异步刷新;支持控件的视图状态;
缺点是页面生命周期比CallBack长,只要在更新区域(UpdatePanel)里的控件不管是否有改变都会回传到服务器并且重新渲染 (Render),造成了多余的负担;引发回传的控件(Tiggers)必须实现IPostBackEventHandler, IPostBackDataHandler 或者INamingContainer.接口。
PS:自此ArcGIS Server9.3 AJAX系列文章就已经全部更新结束了,欢迎交流。
个人blog地址:
http://geospatialthinking.blogbus.com/
http://blog.3snews.net/?222/ -
ArcGIS Server9.3 AJAX系列(三)之ASP.NET AJAX解决方案 - [ArcGIS Server]
2009-12-16
上篇我们介绍了ArcGIS Server9.3 AJAX的Client Callback解决方案。这一方案是92版本所支持的,在最近的93版本中仍然支持。不过93版本又支持另一种最新的AJAX解决方案,我们称之为ASP.NET AJAX解决方案。
注:EDN帮助文档上称之为ASP.NET AJAX partial postback solutions,其实就是对应着ASP.NET AJAX技术。
2007年的时候微软发布了ASP.NET AJAX开发框架,VS2008中默认安装,该框架提供了一个完整的客户端——服务器异步通信的方案。AJAX框架提供了一组AJAX控件 (ScriptManager、UpdatePanel等服务器控件)和API管理异步通信,同时通过客户端的Microsoft AJAX Library动态更新前台页面。这就使得开发者甚至不用编写客户端脚本就能实现局部刷新。
产生局部页面回送(partial page postback)的控件我们称之为触发器,它必须支持IPostBackEventHandler,IPostBackDataHandler或 INamingContainer接口,并且由ScriptManager注册。Web ADF空间事实上大都继承了IPostBackEventHandler接口,也都被ScriptManager所注册,比如 Map,OverviewMap,Toolbar等。而TOC有些不同,它继承了PostBackControl类,该类实现了 IPostBackEventHandler接口。值得一提的是,页面中存在ScriptManager时,Web ADF会选择partial postback解决方案。
关于UpdatePanel与Web ADF,有几点需要再强调一下。一,我们常将服务器控件放在UpdatePanel中以实现局部页面刷新(partial page rendering)。事实上,我们也可以将它们放在UpdatePanel外,这种方式只需要在页面载入时用ScriptManager注册触发回送的 控件就可以了。二,Web ADF已经包含了SciptManager的注册、触发回送的事件以及如何更新客户端的页面内容,因此ADF不需要用UpdatePanel包含。更糟糕 的是,如果将ADF放进UpdatePanel中,将会降低效率。因此,我们极力不推荐将ADF放在UpdatePanel里。
如Client Callback一样,按触发的控件是否Web ADF,ASP.NET AJAX的使用情景也分两种:
一、Web ADF 触发局部页面回送
这种情景与Client Callback的第一种情景几乎一样。不同之处在于,ASP.NET AJAX通过将CallbackResults注册成items的形式由ScriptManager返回。

二、非Web ADF触发局部页面回送
在这种情景下,又有三种选择,分别是UpdatePanel,data items,dynamic script blocks。每一种选择都是微软所支持的标准模式。前面提到将ADF放进UpdatePanel实现刷新将引起效率下降,因此主要看一下另两种选择
(1)dynamic script blocks
ScriptManager允许在服务器端构建JavaScript函数块,在客户端运行。对于ADF的刷新,script block一般会调用processCallbakResult函数来处理服务器端传来的CallbackResults。Note,在使用此方式时,页 面中必须包含有UpdatePanel控件,但UpdatePanel可以为空。
这种方法的缺陷在于需要对CallbackResult进行转义字符的转换,而在C#与VB.NET中并不相同,需要注意。另一个可能的缺陷在于所有的registed script blocks都会贮存于内存,有可能会导致不必要的问题。
这种方法也有一些好处。一个是不需要像UpdatePanel那样实现完全刷新,只部分刷新需要更新的项目。另一个好处在于不需要定制客户端的处理代码,可以都交由processCallbakResult函数来处理。
(2)data items
该方法需要先插入一段自定义的JavaScript函数用来注册data item的异步响应处理函数,该函数会将服务器传来的data items传送给processCallbackResult函数来处理。JavaScript函数如下所示:
<script>
Sys.Application.add_init(onInitFunction);
// Called once during application initialization
function onInitFunction()
{
Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(AsyncResponseHandler);
}
// Called whenever a response to a partial postback is processed on the client
function AsyncResponseHandler(sender, args)
{
var dataItems = args.get_dataItems();
if (dataItems['__Page'] != null)
ESRI.ADF.System.processCallbackResult(dataItems['__Page']);
}
</script>
另外,对每一个data item,都需要ScriptManager注册,例如:
ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), false);
data item的请求响应示意图如下:
-
ArcGIS Server9.3 AJAX系列(二)之Client CallBack解决方案 - [ArcGIS Server]
2009-12-12
之前的文章有提到ArcGIS Server93提供了两种AJAX模式,一种是client callback模式,一种是partial postback模式。本篇将主要介绍ArcGIS Server的script. callback解决方案,对应client callback模式。
Client Callback模式,我们称之为客户端回调。使用这种AJAX模式时,处理客户端请求的服务器控件必须实现ICallbackEventHandler 接口。该接口提供了两个方法,GetCallbackResult和RaiseCallbackEvent。通过这两个方法所实现的功能主要是:从客户端 接收一个数据参数,在服务器端获取这个参数,并执行一个实现所需功能的事件,最后返回客户端所需结果数据。 通俗点说,RaiseCallbackEvent就是接收客户端的指令,然后对其进行处理,最后通过GetcallbackResult返回给客户端。这 就是客户端回调的机理。
另 外有几点需要特别说明。一,客户端在请求时实际上调用了WebForm_DoCallback函数,这个函数被包含在ASP.NET System.Web.dll中,是ASP.NET为实现客户端回调提供的一个底层函数,它封装了一些AJAX实现的细节,可以方便开发人员实现快速开 发。二,任何服务器端控件,只要实现了ICallbackEventHandler接口都可以实现对客户端请求的相应,并返回客户端,Page也是一种服 务器控件,它也实现了这一接口。所有的Web ADF控件其实也都实现了这一接口,因此很多情况下我们不需要明确的对ADF控件的内容进行更新,因为它可以自动更新。
下面来看看客户端回调使用的几种情景:
(一)仅由Web ADF控件处理客户端请求
这 种情景的流程如下图所示,服务器端的Web ADF控件处理客户端发来的请求,生成一个或多个CallBackResults,以序列化的JSON字符串传回客户端,交由客户端Web ADF JavaScript的函数processCallbackResult处理。这个函数位于aspnet_client文件夹下的 ESRI.ADF.System.debug.js文件中,是Web ADF JavaScript库用来解析JSON字符串,修改客户端内容的函数。
这 种方案其实经常出现在自定义ToolBarItem实现一些功能的情境下。由于所有的Web ADF控件都实现了ICallbackEventHandler接口,也就意味着这些控件实现了GetCallbackResult和 RaiseCallbackEvent方法。当通过Toolbar与Map进行交互时,会自动调用Map的以上两种方法,实现地图的自动刷新。如下图所 示:
NOTE:这张图是EDN的解释图,但是这张图是92版本的,93版本的processCallbackResult函数位于aspnet_client文件夹下的ESRI.ADF.System.debug.js文件中。
另外,有时候也需要更新页面上其他非ADF控件的内容,这可以通过定制CallbackResult实现。
(二)由非Web ADF控件处理客户端请求,Web ADF JavaScript处理服务器响应
下面这两张图描述了和第一种情形类似的过程,只不过将客户端的Web ADF换成了页面上的其他非Web ADF控件。这直接导致服务器端处理客户端请求的控件由Map变成了Page。
这张情况使用的范围更广,因为不可能所有的功能都放到Toolbar上去实现。

(三)由非Web ADF控件处理客户端请求,在客户端自定义JavaScript函数处理服务器响应
这 也是三种情景中最难的一种情况,因为所有的服务器逻辑以及客户端的相应代码都需要设计人员自己定制。下面这段代码中的 customFunction就是我们需要在客户端自己定义的相应函数,它负责处理服务器发来的原始callback字符串。要知道如何解析 callback字符串,就必须知道其构造模式,之前提到的processCallbackResult函数就是这样一个解析函数,我们可以参照它编写我 们的定制函数。
[C#]
string m_ADFCallbackFunctionString =
Page.ClientScript.GetCallbackEventReference(this, "message", "customFunction", "context", "handleError", true);
总结:总体上说来,第一种情景比较适合基于Toolbar的应用,第二种情景则应用很广,应该是Server开发人员用得最多的方案,第三种情景则比较适合于对 Server的整个AJAX架构非常清楚,对Callback字符串解析比较了解,并且希望可以定制一些Server所不具有功能的高级开发人员所用。 -
ArcGIS Server9.3 AJAX系列(一)之CallbackResults - [ArcGIS Server]
2009-12-10
NOTE:本系列面向ArcGIS Server for .NET ADF开发人员,并假设其已经具备了基本的ASP.NET及AJAX知识。
ArcGIS Server93的Web ADF为开发人员提供了可以在AJAX环境中管理客户端与服务器之间传输的框架。这个框架称之为“callback results framework“,包括服务器端的一些类(CallbackResultCollection,CallbackResult)及控件(Web ADF controls)和客户端的JavaScript库(Web ADF JavaScript),如下图所示。
服 务器与客户端之间的响应是通过CallbackResult来实现的。事实上,一个CallbackResult是由服务器端的Web ADF control生成的、特定的、以JSON格式化的字符串。所有的Web ADF controls都具有CallbackResults属性,通过CallbackResultsCollection可以添加、删除这些 CallbackResults,或者将其转换为字符串显示。当然,也可以自己定义一个CallbackResult,而不是由服务器控件生成,这将在后 面的内容中介绍。服务器端将CallbackResult传到客户端之后,就交由客户端的Js函数 ESRI.ADF.System.processCallbackResult()来实现客户端内容的刷新。总体上说来,callback result框架简化了开发人员的工作,以异步的方式实现了ADF以及非ADF控件内容的刷新。
按照需要刷新控件的不同,我们分Web ADF控件和非Web ADF控件的刷新两部分来介绍。
一、Web ADF控件的刷新
Web ADF为开发者提供了一系列的控件,比如常用的Map、Toc、Toolbar等。改变地图范围、图层是否可视、地图渲染等都需要刷新上述控件。之前提到 每个ADF控件都具有CallbackResult属性,我们需要做的就是将需要刷新的ADF控件的CallbackResult复制到 Map.CallbackResults,再返回给客户端的Web ADF Js函数processCallbackResult()处理。
例如,添加了一个新的图层,需要刷新Map以及Toc,我们就需要添加如下代码:
Toc1.Refresh();
Map1.CallbackResults.CopyFrom(Toc1.CallbackResults);
实际的过程如下图所示:
在Web ADF控件之间管理callback result依赖于CallbackResultCollection类。它提供了一些方法,可以方便的添加、删除CallbackResult。最常用 到的包括Add方法和CopyFrom方法。前者用于向CallbackResultCollection添加自定义的CallbackResult实 例,后者用于复制某个CallbackResultCollection实例到另一个CallbackResultCollection实例。当然,你也 可以用ToString方法将CallbackResult转换为字符串。更多关于CallbackResultCollection类的使用请参照 ArcGIS Server的离线帮助,这里不一一赘述。
这里需要强调的是,并不是所有ADF控件的刷新都需要明确的在服务器调用刷新方 法,这在Map控件上体现的尤为明显。比如,地图范围的改变或者地图比例的变化都会引起Map控件自动更新其callback result collection。其他情况,如更改地图的可见性或者添加删除某个地图资源都需要明确调用刷新方法。下面列出一些Web ADF控件之间的内联关系,在这些情况下,不需要明确调用刷新方法。
1.当工具栏控件绑定到地图控件,在工具栏上的任何操作都会自动将地图的callback result添加到工具栏的call back result collection。
2.当Toc控件绑定到地图控件,控制Toc里图层可见性的按钮也会实现自动刷新。
二、非Web ADF控件的刷新
页 面中除了Map、TOC等ADF控件,一般还包含有很多非ADF控件,比如Button、Label、GridView等等。刷新这些控件的内容,可以完 全脱离ArcGIS Server的CallbackResult,比如用UpdatePanel。如果你还想使用CallbackResult,当然也是可以的,但必须自己 定制CallbackResult字符串。
CallbackResult类定义了一些静态方法可以方便开发者快速定制自己刷新客户端非Web ADF控件的内容。如下表所示:CallbackResult
Static MethodDescription CreateSetContent Set the outerHTML property of an html element. CreateSetInnerContent Set the innerHTML property of an html element. CreateSetImageSource Set the src property of an image element. CreateJavaScript Execute JavaScript. on the client. CreateIncludeJavaScript Include JavaScript. on the client CreateIncludeStyleSheet Include a CSS style. sheet on the client
服 务器端定制的CallbackResult实例都会被客户端的Web ADF Javascript函数processCallbackResult()处理。processCallbackResult函数将包含以下代码来处理定 制的CallbackResult内容:[JavaScript]if(action==='javascript') {
var method = function() {
try { eval(params[0]); }
. . .}
else if (action==="content") {
var o = $get(controlID);
if (o) { o.outerHTML=params[0]; }
. . .}
else if (action==="innercontent") {
var o2 = $get(controlID);
if (o2) { o2.innerHTML=params[0]; validResponse = true; }
. . .}
else if (action==="image")
{
var o3 = $get(controlID);
if (o3) { o3.src = params[0]; }
. . .}
else if (action=='include') {
var id = params[0];
var elm = (id?$get(id):null);
. . .
if(elm) { elm.parentNode.removeChild(elm); }
document.getElementsByTagName('head').item(0).appendChild(elm);
. . .}最后要强调的是,无论使用哪种AJAX模式,回调技术(callback)还是部分页面刷新(partial postback,或称为ASP.NET AJAX),callback result的内容以及客户端处理callback result的函数都是一样的。
下一篇将介绍基于ToolControl使用ArcGIS Server AJAX框架的方法。 -
ArcGIS Server9.3 AJAX系列(for .NET ADF)之开篇 - [ArcGIS Server]
2009-12-10
最近一直在研究ArcGIS Server 9.3的AJAX技术,网上也有一些系列文章有提到,不过很多都只涉及到ASP.NET的Client CallBack解决方案,而9.3版开始支持ASP.NET AJAX解决方案,即EDN帮助里的ASP.NET AJAX partial postback solutions。
这个系列准备分以下几个章节介绍:
一、ArcGIS Server的CallbackResults
二、基于ToolControl使用ArcGIS Server AJAX框架
三、ArcGIS Server9.3 AJAX之Client CallBack解决方案
四、ArcGIS Server9.3 AJAX之ASP.NET AJAX解决方案
敬请期待! -
ArcGIS Server中圆查询时碰到的一些问题总结 - [ArcGIS Server]
2009-12-07
前一篇帖子曾经说到分别用点选、线选、多边形选来查询要素的信息,这篇来谈谈圆查询。
刘光的那本ArcGIS Server的书上有写到圆形查询。由于ADF在ADF.WEB.GEOMETRY里并没有提供Circle类,因此该书将圆近似为Polygon类实现查询。我一开始并不是很认同这种做法,主要是考虑到精度上的问题(后来实践后才觉得用这种方法还是有些道理的)。而ArcGIS Server比ArcIMS强就在于可以利用AO来在服务器端做一些分析。所以,我一直想借助于AO中ITopologicalOperator接口的buffer方法来构建圆,进而实现圆查询。
有了思路就开始动手了。先将ToolEventArgs转换为MapCircleEventArgs。当然还有一个CircleEventArgs,不过ESRI社区的北斗星在这篇文章中指出CircleEventArgs的radius返回的半径可能会不正确,并且CircleEventArgs的radius参数单位是屏幕单位。我也进行了一下实验,发现CircleEventArgs.Radius和MapCircleEventArgs.MapRadius返回的结果不一样,并且MapRadius返回的应该是原始数据的单位,而非屏幕单位。不过这里的MapCircleEventArgs.MapRadius还是会有些问题,这个下面再说。
得到了圆的中心点和半径后,就是要在服务器端调用ITopologicalOperator的Buffer方法构建圆。但是经过Buffer以后的Geometry只有两个点了,而且坐标还是一样的,也就没法用我们之前的其他查询的代码来高亮和显示结果,而需要在服务器端继续用AO来写查询,得到IFeatureCursor对象一步步遍历Feature,读取Feature信息。这显然不是我们需要的,我们更想实现之前写好代码的重用。所以,又回到了之前那本书上的方法,也是ArcGIS Server自带例子Select Buffer里的方法,将圆近似为Polygon类。主要代码如下:
public static Polygon GetMapCircle(Map map, MapCircleEventArgs cirArgs)
{
Polygon poly = new Polygon();
try
{
ScreenPoint screenPoint = cirArgs.CenterPoint;
double radius = cirArgs.MapRadius/4;
Point mapPoint = Point.ToMapPoint((int)screenPoint.X, (int)screenPoint.Y, map.Extent, (int)map.Width.Value, (int)map.Height.Value);
System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
path.AddEllipse((float)(mapPoint.X - radius), (float)(mapPoint.Y - radius), (float)(radius * 2), (float)(radius * 2));
float flattening = (float)(radius / 1000);
path.Flatten(null, flattening);
PointCollection adfPointCollection = new PointCollection();
foreach (System.Drawing.PointF pointF in path.PathPoints)
{
adfPointCollection.Add(new Point(pointF.X, pointF.Y));
}
Ring ring = new Ring();
ring.Points = adfPointCollection;
RingCollection rings = new RingCollection();
rings.Add(ring);
poly.Rings = rings;
}
catch
{
return null;
}
return poly;
}刚才还提到MapCircleEventArgs.MapRadius参数会出现问题,就是它的值大约是真实圆半径的4倍左右,在北斗星的文章里用到了。当时我就很纳闷,为什么要除以4,至今我也没有搞懂。另外亚洲之鹰也在其BLOG上指出了该错误。但为何要除以4仍然是个问题,估计要询问ESRI的技术支持了。
最后总结一下。实现圆查询有两种思路。第一种是通过ITopologicalOperator的Buffer方法实现,但需要继续编写查询代码,处理读取的要素值。另一种是通过将圆近似为多边形,经Web.DataSources.IQueryFunctionality实现,还可以同时实现高亮等,很好的达到了代码重用的目的。
当然,在AO里处理数据还是很强大的,毕竟有些功能必须要通过AO来实现,所以在以后的学习过程中要根据情况选择最优的方法。
-

-
ArcGIS Server之多种几何查询 - [ArcGIS Server]
2009-12-02
Identify已经不能满足用户的需要了,比如用户需要了解一定区域内的情况,就必须要用到框选。因此,本文将讲述如何实现ArcGIS Server的各种空间查询的思路,包括点选、线选、框选、多边形选、圆选等。思路大体如下:
1.继承IMapServerToolAction接口,获取ToolEventArgs,并转成相应的几何参数。
比如客户端操作为画点,则将ToolEventArgs转换为PointEventArgs;如果客户端操作为画多边形,则将ToolEventArgs转换为PolygonEventArgs;其它以此类推。
2.获得对应的几何参数后,则要将它转换成Web.Geometry下的各种几何体
这部分对于AE比较熟悉的同学会比较容易,以polygon为例,要先将参数转为点集合,再将屏幕坐标转换为地图坐标,最后有点构线(ring),由线集合(Rings)构面。
public static Polygon GetMapPolygon(Map map, PolygonEventArgs polyArgs)
{
Polygon poly = new Polygon();
try
{
System.Drawing.Point[] points = polyArgs.Vectors;
PointCollection pc = new PointCollection();
foreach (System.Drawing.Point poi in points)
{
pc.Add(Point.ToMapPoint(poi, map.Extent, (int)map.Width.Value, (int)map.Height.Value));
}
Ring ring = new Ring();
ring.Points = pc;
RingCollection rings = new RingCollection();
rings.Add(ring);
poly.Rings = rings;
}catch
{
return null;
}
return poly;
}3.在服务器端进行空间查询
由于这一步的代码对各种几何查询具有高可用性,因此将查询函数的参数抽象为Geometry,以实现代码的重用,最后数据以DataSet的格式返回。
public static DataSet SearchByGeometry(Map map, Geometry mapGeo)
{
if (map == null)
return null;
//遍历functionality
IEnumerable func_enum = null;
func_enum = map.GetFunctionalities();
DataSet ds = new DataSet();
SpatialFilter spatialFilter = new SpatialFilter();
spatialFilter.ReturnADFGeometries = false;
spatialFilter.MaxRecords = 1000;
spatialFilter.Geometry = mapGeo;
try
{
foreach (IGISFunctionality gisFunc in func_enum)
{
IGISResource gisResource = null;
gisResource = gisFunc.Resource;
bool supported = false;
supported = gisResource.SupportsFunctionality(typeof(IQueryFunctionality));
if (!supported)
continue;
IQueryFunctionality qFunc = null;
qFunc = gisResource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null) as IQueryFunctionality;
string[] layerIDs, layerNames;
qFunc.GetQueryableLayers(null, out layerIDs, out layerNames);
for (int i = 0; i < layerIDs.Length; i++)
{
DataTable table = qFunc.Query(null, layerIDs[i], spatialFilter);
if (table == null || table.Rows.Count == 0)
continue;
table.TableName = layerNames[i];
ds.Tables.Add(table);
}
}
}
catch
{
return null;
}
return ds;
}4.显示查询结果以及高亮
这步在之前的Identify操作中已经实现,可以直接调用,更好的达到代码重用。
另,清除高亮结果的操作也很简单。我们在前一篇文章中曾经提到高亮显示有两种方法。
一种方式是将Graphics添加到每一个MapFunc的CustomGraphics。这种方式对应的清除方法即将CustomGraphics设置为NULL,再刷新。
另一种方式是新建Graphic数据源。同样的,这种方式的清除方法是将其resource的Graphics进行clear,并刷新。主要代码如下:
#region IServerAction Members
void IServerAction.ServerAction(ToolbarItemInfo info)
{
Map map = info.BuddyControls[0] as Map;
ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality mapFunc = map.GetFunctionality("HighLight") as ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality;
if (mapFunc == null)
return;
MapResource graphicResource = mapFunc.Resource as MapResource;
graphicResource.Graphics.Clear();
HighlightResults.RefreshMap(map, "HighLight");
}
#endregionPS:之前做Server的时候一直有一种体会,就是很多代码在定义变量的时候将所在的命名空间名称也加上了。这样的好处是避免不同命名空间用到相同名称,不好之处在于开发者看得会很累。我的感觉是,能不用时不用,实在冲突了再加上。
-
ArcGIS Server之高亮查询要素 - [ArcGIS Server]
2009-12-01
GIS中,一般查询要素后,为提醒用户注意,都会在地图上用不同的颜色将要素高亮显示,或者以闪烁实现。
ArcGIS Server中,实现高亮查询要素有两种思路。一是在Manager中新建一个GraphicLayer层,这个层是在内层中的,然后在这个层上将需要高亮显示的要素重新画一遍。另一种思路是设置资源绘图功能的MapDescription属性的CustomGraphic属性。考虑到方法的难易程度,以及通用性,个人感觉用第一种方法更佳。第二种方法参见下面这篇博文:http://www.cnblogs.com/tuncaysanli/archive/2009/06/21/1507738.html
第一种方法的思路如下:
1.获得Manager里的GraphicResource,并在Resource里获取GraphicsLayer。
这个步骤有两个问题需要明确。一,GraphicResource是一种Resource,里面自然可以存1-n个Layer,而每一个Layer又是一个DataTable,两者之间是可以相互转换的。二,ArcGIS Server里的GraphicsLayer有2种,分别是ElementGraphicsLayer和FeatureGraphicsLayer。两种Layer最大的区别在于:ElementGraphicsLayer中可以存储不同类型的Geometry,类似于以前MO或者SO中的动态层,而且它不带属性信息;FeatureGraphicsLayer则相反,每一层只能存储同一几何类型的Geometry,且可以带属性信息。
2.获得查询要素的信息,并转化为Element,添加到ElementLayer中
GraphicElement element = new GraphicElement(geom, System.Drawing.Color.Yellow, System.Drawing.Color.Red);
从上面的代码我们可以发现,ESRI为GraphicElement提供了很多的构造函数,可以方便的新建GraphicElement。比如提供Element的颜色,选择的颜色,高亮的颜色,透明度等等,或者设置默认的style和选择状况下的style。
3.刷新地图,其中resourceName为GraphicResource的Name。
public static void RefreshMap(Map map, string resourceName)
{
if (map.ImageBlendingMode == ImageBlendingMode.WebTier)
{
map.Refresh();
}
else if (map.ImageBlendingMode == ImageBlendingMode.Browser)
{
map.RefreshResource(resourceName);
}
} -
ArcGIS Server之Ajax初体验 - [ArcGIS Server]
2009-11-27
说起Ajax,并不是很陌生了,大三的时候就知道了这个名词。它是Asynchronous Javascript and XmlHttpRequest的缩写。尤其是在线地图中,google maps将ajax技术用得出神入化,极大的提高了用户体验。
最近基于.NET ADF学习ArcGIS Server,不可避免的涉及到了ASP.NET的回调技术。一开始我觉得这种回调技术就是对传统Ajax的封装,给developer提供一个更容易开发的接口,以实现页面的局部刷新。不过网上有人说这两者技术有一些区别,但又没讲的很清楚。找一些ASP.NET的书来看,发现里面确实有很多实现方式,比如UpdatePanel,比如ASP.NET AJAX ControlToolkit,比如ICallbackEventHandler接口。至于其中的异同,优劣,还需要继续深入了解才能明白。
就现在的体会来讲,ArcGIS Server Sample里提供的方法有两种,一个是依赖于.NET本身的回调技术,利用ICallbackEventHandler接口提供的两个方法来实现局部刷新。另一个是ArcGIS的CallBackResult类,将字符串构造好push给每个web adf control来实现页面的局部刷新。
不过ASP.NET AJAX这块还是有很多模糊的地方,需要接下来更系统的学习。一是要参照ASP.NET的书籍,再者可以参照ArcGIS Server的离线帮助,发现这个帮助还是很有用的。
-
GIS职业生涯成功的必要技能 - [Quick Note]
2009-11-21
翻译整理自michalisavraam的博客
原文地址:http://michalisavraam.org/2009/11/the-essential-skills-to-succeed-in-a-gis-career/
GIS技能
1.数字化
2.数据转换
3.数据维护(data maintenance)
4.元数据创建与编辑
5.GIS 分析
6.GIS workflow???
7.模型建立(大概是指类似ArcGIS的model builder)
8.地图制图与设计
For me, 3和8需要加强
编程技能
1.基础编程
2.编程语言
3.面向对象
4.基本GIS架构(CS and BS)
5.网络知识和经验
For me, 4的BS和5需要加强
数据库技能
1.理解数据模型和结构(UML)
2.设计数据模型
3.数据库设计知识
For me,都比较缺乏
项目管理与设计技能
1.转化用户需求到解决方案
2.良好的沟通技能
3.良好的写作技能
4.项目管理技能
For me,都要学习
其他技能
1.将专业知识应用到GIS中
2.熟悉各种平台
3.Detail oriented(没懂)
4.客户支持 -
ESRI也开始关注LiDAR - [LiDAR]
2009-11-19
ESRI刚推出一个免费的培训,介绍LiDAR的一些基础知识,以及如何在ArcGIS中管理与处理LiDAR数据
培训地址:http://training.esri.com/Courses/ts_LidarGetStarted/index.cfm
培训手稿(PDF):http://training.esri.com/Courses/ts_LidarGetStarted/ts_LidarGetStartedSlides1.pdf
接下来还有进阶培训,继续关注
- Managing Lidar Data in ArcGIS
- Using Lidar Data in ArcGIS








