基于Rest的天气服务接口实现研究
2015-01-08左进波
左进波
(中国矿业大学〈北京〉地球科学与测绘工程学院,中国 北京100083)
0 引言
在人们的日常生活中,天气服务随处可见,同时也是不可或缺的生活服务之一。随着移动通讯技术的发展和智能设备的普及,多种多样的移动应用(app)使得人们的生活更加便利,随时打开一款天气应用人们都可以获得最新的天气情况。传统的天气服务接口形式为:用户输入目标城市名,然后得到当地的天气情况,这样一来就没有充分利用移动智能设备的定位功能,本文正是研究通过经纬度信息获取天气情况接口服务的实现。
SuperMap iServer Java是基于Java EE平台构建的面向服务式架构的企业级GIS产品,实现了将传统桌面软件强大的GIS功能以面向服务的组件形式部署在GIS服务器上,实现开发人员调用不同功能的GIS组件来实现应用程序所需要的功能。这样通过将WebGIS应用程序发布在Web应用服务器上,客户端可以直接通过网络访问和使用Web应用程序提供的专业GIS功能服务[1]。
1 SuperMap iServer Java领域服务扩展开发
SuperMap iServer Java不仅是企业级的GIS服务器,同时也是可扩展的服务式开发平台,可扩展性为进行个性化业务逻辑开发提供了方便。SuperMap iServer Java扩展主要分为两个部分:领域空间信息服务扩展(也称为DSS)和iClient客户端扩展。
领域空间信息服务扩展是指用户根据特定的业务逻辑,自行构建出与空间信息有关的空间信息服务,例如气象行业应用的风向符号标志图服务等。领域空间信息服务能够完成通用核心的GIS功能,同时也可以与其他业务系统交互,和特殊的业务模型结合,从而实现特定的服务。
SuperMap iServer Java服务框架是一个三层结构的体系,包括服务提供者、服务组件和服务接口。各个层次的功能和作用如图1所示。服务提供者利用GIS计算内核或者第三方GIS服务实现GIS功能的处理;服务组件对服务提供者提供的功能进行组合和统一封装;服务接口按照不同的服务形式的规则构建servlet或者interface,将服务组件以各种形式对外发布,如将地图服务组件发布为rest风格的地图服务,将数据服务组件发布为wfs服务等[2]。各层次间的调用关系以及依赖注入技术(上下层次模块之间的动态调用)是通过配置文件完成的,这样当任何模块发生改变之后可以很容易的进行配置和改变,这样就实现了动态关联关系的创建,从而有效的提高了效率,提升了模块利用率。
2 实现总体思路与架构设计
根据领域服务扩展开发的特点,通过自定义开发领域服务提供者实现特殊的底层GIS数据功能,通过领域服务组件实现对服务提供者的封装及处理,通过开发服务接口来实现与客户端的对接。
服务接口中需要根据用户所在的地区,也就是用户所在地的经纬度,进而给出当地的天气情况。要进行天气的实时获取,免不了要访问天气服务提供商,这里选择中国天气网作为天气情况服务商,由于中国天气网在获得天气情况时需要用到城市码,这样情况下需要进行空间分析,然后通过点查询得到对应的天气码。
服务接口的实现流程如图2所示,用户将经纬度信息传给接口,接口通过点查询的空间分析将取得对应的天气请求码,通过天气请求码访问中国天气网的数据接口,得到相应的天气数据,然后根据具体需要对天气数据进行个性化定制处理。
天气接口的详细架构如图3所示,服务接口采用Myeclipse 10作为IDE开发环境。服务接口的运作流程为:
(1)客户端调用接口将经纬度信息发送过来;
(2)将经纬度信息生成点要素,并与底图进行点查询;
(3)获得点查询的天气码,请求中国天气网,并获得返回数据;
(4)将数据进行加工处理,返回给用户(客户端)。
3 Rest服务接口实现关键技术
3.1 底图数据准备
数据对于GIS来说十分重要,是GIS系统的核心和灵魂。对于天气服务接口的设计而言,必须要通过底图数据实现空间位置与属性信息的关联和管理。本接口服务设计中底图数据采用中国县级行政区详细区域数据,同时属性数据信息包含兼容中国天气网的天气请求码数据。
3.2 实现领域服务提供者
领域服务提供者在三层中是最底层的,也是调用的底点,在这一层中要实现:根据传递过来的经纬度信息得到天气码供服务组件层使用。具体要做的就是:进行点查询并返回天气码。
启动工作空间为点查询做好准备,其中底图的文件路径通过配置参数类的方式获得。
if(workspace==null)
{
workspace=new Workspace();
workSpaceConnInfo=new WorkspaceConnectionInfo();
workSpaceConnInfo.setType(WorkspaceType.SMWU);
workSpaceConnInfo.setServer(filename);//注意文件路径
if(!workspace.open(workSpaceConnInfo))
{
System.out.println("打开工作空间出现错误了。");
return null;
}
}
通过上层传递的点信息与底图进行空间点查询并获得查询结果值。
Dataset dsarea=datasource.getDatasets().get("全国县级行政区");//获得全国县级行政区数据集
QueryParameter queryparameter=new QueryParameter();
queryparameter.setSpatialQueryObject(gps_point);
queryparameter.setSpatialQueryMode (SpatialQueryMode.WITHIN);
DatasetVector dsvec=(DatasetVector)dsarea;
recordset=dsvec.query(queryparameter);
CityWeatherCode=recordset.getFieldValue("WCode").toString();//城市天气码
}catch(Exception e)
{
System.out.println(" 点 查 询 处 理 出 现 错 误 "+e.getMessage());
}
finally {
recordset.close();
recordset.dispose();//释放资源
workSpaceConnInfo.dispose();//释放资源
workspace.close();
workspace.dispose();
}
服务提供者通过setProviderContext方法获得配置文件中底图的路径信息。在配置文件中配置底图路径参数,并为配置参数类对象赋值,这样就可以通过读取参数类对象从而动态获得文件路径。
@Override
public void setProviderContext(ProviderContext context){
//TODO Auto-generated method stub
GetOverallWeatherParameterJson getoveralljson =context.getConfig(GetOverallWeatherParameterJson.class);
filename=getoveralljson.Getfilename();
}
public class GetOverallWeatherParameterJson{
private String filename=null;
public void Setfilename(String name)
{
this.filename=name;
}
public String Getfilename()
{
return this.filename;
}
}
3.3 实现天气服务组件
服务组件层是中间层也是所有业务封装统一层,这层实现的是:通过调用服务提供者获得天气码,通过天气码进行网络请求,获取请求数据,根据实际需要对数据进行处理,将数据返给接口层。
服务层组件应该继承ComponentContextAware接口,获取上下文对象,进而通过实现setComponentContext方法获取配置文件中相关的配置信息,获得服务提供者,然后才能进行的业务操作。
@Override
public void setComponentContext(ComponentContext context){
//TODO Auto-generated method stub
List<Object> providers=context.getProviders(Object.class);
if(providers!=null)
{
for(Object provider:providers)
{
if(provider instanceof Get Overall Weather Provider)
{
this.getWeatherProvider=(Get Overall Weather Provider)provider;
break;
}
}
}
}
获得服务提供者之后,就可以调用服务提供者获得天气码。
String cityWeatherCode=getWeatherProvider.Get City Wether Code Method(posPointin);
通过天气码进行网络请求,获取请求数据。
strweatherJson=ConnWeatherAPI(cityWeatherCode);
通过ConnWeatherAPI方法获得返回数据,在ConnWeatherAPI方法里进行网络请求,和请求后数据的处理,并返回json数据。
3.4 实现接口层
接口层要做的就是等待客户端连接,接收客户端传递过来的经纬度信息,调用服务组件层取得数据,并将数据返给客户端。接口层要继承JaxrsResourceBase 或者 JaxAlgorithResultSetResource<T>接口,从而通过调用getInterface()接口,获取上下文对象,从而或获取服务组件层[3]。在类前加入标注,表明接口支持的服务组件:
@Component (interfaceClass =com.supermap.Services.GetOverallWeather.GetOverallWeatherComponent.class)。 在 类 前 加 入 标注,表明服务资源位置:@Path("/GetOverallWeather")。在方法前标注限定接口调用方式、请求URL:
@GET
@Path("{inLongitude}/{inLatitude}")
public String GetOverallWeatherJAXRS(@PathParam("inLongitude")String longitude,@PathParam("inLatitude")String latitude){……}
通过上下文对象获得服务组件层对象信息:
GetOverallWeatherComponent getWeatherPosComponent
=interfacecontext.getComponents (GetOverallWeatherComponent.class).get(0);
调用服务组件层获得数据:
strjs=getWeatherPosComponent.GetWeatherJsonMethod(inLongitude,inLatitude);
进行资源文件的配置,配置资源文件主要为了superMap框架能够识别资源。
<resources>
<resource>
<configID>GetOverallWeather</configID>
<implementClass >com.supermap.Services.GetOverallWeather.GetOverallWeatherResource</implementClass>
</resource>
</resources>
4 结束语
本天气服务接口通过SuperMap iServer Java领域服务扩展实现,同时结合点查询空间分析,实现了基于Rest接口服务的实时天气状况的获取,可以满足一般应用的天气服务,具有极大的应用价值。应用过程中由于使用了多次的网络请求服务使得响应速度对于网络状况的依赖性很强,这在一定程度上会影响数据加载速度,这也为以后研究实现更加便捷、快速响应的接口服务提供了良好的借鉴和参考。
[1]汪秀兵,张广弟,耿衬.基于 SuperMap iServer的赣州市旅游信息服务发布研究[J].测绘标准化,2012(2):25-28.
[2]SuperMap图书编委会.GIS工程师训练营 SuperMap iServer Java从入门到精通[M].北京:清华大学出版社,2012.
[3]北京超图软件股份有限公司.SuperMap iServer Java 6R(2012) 帮助[Z].2012.