定义全新的服务接口 |
服务接口的实现形式如下:
@Interface(componentTypes = { com.supermap.services.components.Map.class }, optional = false, multiple = false)
@Protocol(names={"BingMaps"})
public class BingMapsServlet extends HttpServlet implements InterfaceContextAware {
...
}
其中:
在服务接口实现类中,可以通过 InterfaceContextAware 接口获取服务接口上下文,通过服务接口上下文,可以获取获取服务接口配置信息,从而获取服务组件。
服务接口配置信息在 iserver-services-interfaces.xml 中(详见服务配置文件结构),配置服务接口时定制,结构由服务接口配置类确定。服务接口配置如下:
<interface class="com.supermap.sample.SampleServlet" name="sampleinterface">
<config class="com.supermap.sample.SampleServletSetting">
<param1>default</param1>
...
</config>
</interface>
其中,SampleServletSetting 是 SampleServlet 对应的配置类,param1对应 SampleServletSetting 类的属性。
在服务接口实现类中,可以通过 InterfaceContextAware 接口获取服务接口上下文,通过服务接口上下文,可以获取获取服务接口配置信息(即以上配置),具体方式如下:
@Interface(componentTypes = { com.supermap.services.components.Map.class }, optional = false, multiple = false) @Protocol(names={"SampleInterface"}) public class SampleServlet extends HttpServlet implements InterfaceContextAware { ... public void setInterfaceContext(InterfaceContext context) { //从服务接口上下文中获取服务接口配置 SampleInterfaceConfig sampleConfig = context.getConfig(SampleInterfaceConfig.class); } }
SampleInterfaceConfig 对象即对应接口配置中的<config class="com.supermap.sample.SampleServletSetting"/> 配置项。
如果服务接口无需额外配置,则可以不定义服务接口配置类。
SuperMap iServer 中,服务组件通过相匹配的服务接口发布为 Web 服务,在服务接口实现类中,可通过服务接口上下文获取服务组件,从而获取相应的 GIS 功能。获取方式如下:
@Interface(componentTypes = { com.supermap.services.components.Map.class }, optional = false, multiple = false) @Protocol(names={"SampleInterface"}) public class SampleServlet extends HttpServlet implements InterfaceContextAware { ... public void setInterfaceContext(InterfaceContext context) { //从服务接口上下文中获取服务组件(这里是地图服务组件) List components = context.getComponents(Map.class); ... } }
服务接口决定了 GIS 功能提供的形式,扩展服务接口,可以丰富 GIS 功能的提供形势,以适应更多客户端需求。
这里实现一个 BingMaps 出图接口,提供跟 BingMaps REST 服务静态出图类似的 REST 接口。你可以在 %SuperMap iServer_HOME%/samples/DSSE/BingMapsInterfaceSample 位置找到该示例的源代码。
按照 BingMaps 的 REST 接口,访问如下 URI 可获取一张地图:
http://dev.virtualearth.net/REST/v1/Imagery/Map/ Road?mapArea=30.0,100.0,50.0,120.0&mapSize=512,512&key=BingMapsKey
其中,“Road”是 BingMap 提供的地图名称,mapArea 是出图的地理区域(南纬,西经,北纬,东经),mapSize 是出图大小(宽,高), BingMapsKey 是 BingMaps 的授权密匙,参见获取 BingMaps Key(http://msdn.microsoft.com/en-us/library/ff428642.aspx)。
实际上,BingMap 的 REST 接口有更多的参数,作为示例,这里“BingMaps 出图接口”只模拟实现地图名称、地理区域、出图大小3个参数。
BingMapServlet 实现类代码如下,实现了处理 URI,调用 Map 组件响应正确图片的功能:
package com.supermap.sample.serviceinterface; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLDecoder; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.supermap.services.Interface; import com.supermap.services.InterfaceContext; import com.supermap.services.InterfaceContextAware; import com.supermap.services.components.Map; import com.supermap.services.components.MapException; import com.supermap.services.components.commontypes.ImageOutputOption; import com.supermap.services.components.commontypes.MapImage; import com.supermap.services.components.commontypes.MapParameter; import com.supermap.services.components.commontypes.OutputFormat; import com.supermap.services.components.commontypes.Rectangle; import com.supermap.services.components.commontypes.Rectangle2D; import com.supermap.services.components.commontypes.RectifyType; import com.supermap.services.components.commontypes.ReturnType; import com.supermap.services.interfaces.Protocol; import com.supermap.services.util.Tool; /** * <p> * BingMaps REST 地图服务 URI:http://dev.virtualearth.net/REST/v1/Imagery/Map/ imagerySet?mapArea=mapArea&mapSize=mapSize&key=BingMapsKey * imagerySet:地图名称 * mapArea:南纬,西经,北纬,东经 * mapSize:图片宽度,图片高度 * BingMapsKey:BingMaps 访问密匙 * * http://dev.virtualearth.net/REST/v1/Imagery/Map/ Road?mapArea=30.0,100.0,50.0,120.0&mapSize=512,512&key=BingMapsKey * http://localhost:8090/iserver/services/map-world/bingmaps/世界地图?mapArea=30.0,100.0,50.0,120.0&mapSize=512,512 * </p> */ @Interface(componentTypes = { com.supermap.services.components.Map.class }, optional = false, multiple = false) @Protocol(names={"BingMaps"}) public class BingMapsServlet extends HttpServlet implements InterfaceContextAware { private Map mapImpl; public BingMapsServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取服务的根路径,在 iServer 中,根路径为:/iserver/services/<servicecomponent>/<serviceinterface> String rootPath = request.getContextPath() + request.getServletPath(); String requestURI = request.getRequestURL().toString(); java.util.Map<String, String> paramMap = request.getParameterMap(); int rootPathIndex = requestURI.indexOf(rootPath); String remainPart = requestURI.substring(rootPathIndex + rootPath.length() + 1); //地图名称 String mapName = (remainPart.indexOf('/') == -1 ? remainPart : remainPart.substring(0, remainPart.indexOf('/'))); mapName = URLDecoder.decode(mapName,"utf-8"); //地理范围和图片大小 String mapArea = (String) request.getParameter("mapArea"); String mapSize = (String) request.getParameter("mapSize"); String[] mapAreaStrs = mapArea.split(","); String[] mapSizeStrs = mapSize.split(","); if(mapAreaStrs.length < 4||mapSizeStrs.length < 2){ return; } Rectangle2D viewBounds = new Rectangle2D(Double.valueOf(mapAreaStrs[1]),Double.valueOf(mapAreaStrs[0]), Double.valueOf(mapAreaStrs[3]),Double.valueOf(mapAreaStrs[2])); Rectangle viewer = new Rectangle(0, 0, Integer.valueOf(mapSizeStrs[0]), Integer.valueOf(mapSizeStrs[1])); try { MapParameter mapParameter = this.mapImpl.getDefaultMapParameter(mapName); mapParameter.viewBounds = viewBounds; mapParameter.viewer = viewer; mapParameter.name = mapName; mapParameter.rectifyType = RectifyType.BYVIEWBOUNDS; //返回图片流 mapParameter.returnType=ReturnType.BINARY; ImageOutputOption outputOption = new ImageOutputOption(); //图片格式为 PNG outputOption.format = OutputFormat.PNG; MapImage mapImage=null; if (mapImpl != null) { mapImage = mapImpl.getMapImage(mapParameter, outputOption); } if(mapImage.imageData!=null){ //获取 mapImage 中的图片流,写入 HTTP 响应 response.getOutputStream().write(mapImage.imageData); } } catch (MapException e) { e.printStackTrace(); } } public void setInterfaceContext(InterfaceContext context) { //从服务接口上下文中获取服务接口配置,这里没有配置 //InterfaceConfig interfaceConfig = context.getConfig(InterfaceConfig.class); //从服务接口上下文中获取服务组件(这里是地图服务组件) List<Map> components = context.getComponents(Map.class); if (components != null) { for (Object component : components) { if (component instanceof Map) { this.mapImpl = (Map) component; break; } } } } }
编译后,将 Jar 包放到 %SuperMap iServer_HOME%\webapps\iserver\WEB-INF\lib 目录下。
在服务接口配置文件中(参见:服务配置文件结构)中添加 BingMapsREST 服务接口,即添加< interface />节点如下:
<interface class="com.supermap.sample.serviceinterface.BingMapsServlet" name="bingmapsrest">
</interface>
修改 map-world 地图服务组件的配置,添加 bingmapsrest 到 map-world 绑定的服务接口,如下:
<component class="com.supermap.services.components.impl.MapImpl" interfaceNames="rest,wms111,wms130,wmts100,bingmapsrest"
name="map-world" providers="ugcMapProvider-World">
<config class="com.supermap.services.components.MapConfig">
</config>
</component>
对 URI:http://localhost:8090/iserver/services/map-world/bingmaps/世界地图?mapArea=10.0,100.0,50.0,180.0&mapSize=512,512执行 GET 请求,获取 png 格式的地图图片如下: