0.前言
研究 arcgis object的代码是十分重要的,对于学习arcObject太重要了,因为没有这些代码,学习混乱的arcObject将会更佳的困难。
我的arcgis server 是10.0 for java的,所有核心是arcObjects.jar文件:E:\Program Files\ArcGIS\Server10.0\java\lib\arcobjects.jar
arcObject sample在:E:\Program Files\ArcGIS\DeveloperKit10.0\java\samples\arcobjects
其中ao的javadoc文档在:E:\Program Files\ArcGIS\DeveloperKit10.0\java\docs\eclipse\plugins\com.esri.arcgis.doc\doc.zip
在eclipse中配置arcGIS的javadoc地址为:jar:file:/E:\Program Files\ArcGIS\DeveloperKit10.0\/java/docs/eclipse/plugins/com.esri.arcgis.doc/doc.zip!/api/arcobjects
这样就可以通过eclipse迅速打开 javadoc了。
当然通过:E:\Program Files\ArcGIS\DeveloperKit10.0\java\docs\startJavaHelp.bat 也可以打开单独的eclipse帮助形式的 文档,单独的。这个doc.zip文件解压后很大,所以这种方式很好。
下面我要好好的分析下 sample代码
1.arcgis sample代码之SOE示例代码PageLayout REST Server Object Extension 的分析
在eclipse中创建了arcgis sample代码的pageLayout Rest Server Object Extension。这个SOE的功能是 将地图服务的 layout给画出来并缓存到C:\arcgisserver\arcgisoutput\目录下。
在代码的bitmaps有个图片,是此SOE的示意图。
其中在竹资源下有一个操作(操作就是有参数的rest资源) ,还有一个资源: ,其实本质上一样,这个资源只是指定了三个参数而已。
在src/arcgissample.soe包下 有 PageLayoutImpl.java 和 PageLayoutSOE.java
pageLayoutImpl.java
/* Copyright 2010 ESRI* * All rights reserved under the copyright laws of the United States* and applicable international laws, treaties, and conventions.* * You may freely redistribute and use this sample code, with or* without modification, provided you include the original copyright* notice and use restrictions.* * See the use restrictions at <your ArcGIS install location>/DeveloperKit10.0/userestrictions.txt.* */package arcgissamples.soe;import java.util.logging.Logger;import com.esri.arcgis.carto.AlternatingScaleBar;import com.esri.arcgis.carto.IActiveView;import com.esri.arcgis.carto.IElement;import com.esri.arcgis.carto.IFrameElement;import com.esri.arcgis.carto.IGraphicsContainer;import com.esri.arcgis.carto.IImageDescription;import com.esri.arcgis.carto.IImageDisplay;import com.esri.arcgis.carto.IImageType;import com.esri.arcgis.carto.ILayoutImage;import com.esri.arcgis.carto.ILegend;import com.esri.arcgis.carto.IMap;import com.esri.arcgis.carto.IMapFrame;import com.esri.arcgis.carto.IMapServerLayout;import com.esri.arcgis.carto.IMapServerObjects;import com.esri.arcgis.carto.IMapSurroundFrame;import com.esri.arcgis.carto.ImageDescription;import com.esri.arcgis.carto.ImageDisplay;import com.esri.arcgis.carto.ImageType;import com.esri.arcgis.carto.Legend;import com.esri.arcgis.carto.MapServer;import com.esri.arcgis.carto.MarkerNorthArrow;import com.esri.arcgis.carto.PageLayout;import com.esri.arcgis.carto.TextElement;import com.esri.arcgis.carto.esriImageFormat;import com.esri.arcgis.carto.esriImageReturnType;import com.esri.arcgis.carto.esriViewDrawPhase;import com.esri.arcgis.geometry.Envelope;import com.esri.arcgis.geometry.IEnvelope;import com.esri.arcgis.geometry.IGeometry;import com.esri.arcgis.geometry.IPoint;import com.esri.arcgis.geometry.Point;import com.esri.arcgis.system.IUID;import com.esri.arcgis.system.UID;public class PageLayoutImpl{ private MapServer serverObject; // SOE metadata private int width; private int height; private int dpi; //Document related metadata private String mapName; private IMap map; private IActiveView activeView; private IActiveView pageActiveView; private IMapServerObjects serverObjects; private PageLayout pageLayout; // SOE result private String outputUrl; private static final Logger logger = Logger.getLogger(PageLayoutImpl.class.getName()); // public constructor. public PageLayoutImpl(MapServer serverObject, int width, int height, int dpi) { this.serverObject = serverObject; this.width = width; this.height = height; this.dpi = dpi; this.outputUrl = null; } public void generatePageLayout() throws Exception { try { mapName = serverObject.getDefaultMapName(); map = serverObject.getMap(mapName); activeView = coerce(map); serverObjects = coerce(serverObject); pageLayout = coerce(serverObjects.getPageLayout()); pageActiveView = coerce(pageLayout); IGraphicsContainer graphicsContainer = coerce(pageLayout); graphicsContainer.reset(); IFrameElement frameElement = graphicsContainer.findFrame(map); IMapFrame mapFrame = coerce(frameElement); //create a legend IUID uid = coerce(new UID()); uid.setValue(Legend.getClsid()); IMapSurroundFrame legendFrame = mapFrame.createSurroundFrame(uid, null); legendFrame.getMapSurround().setName("Map Legend"); IElement legendElement = coerce(legendFrame); legendElement.activate(pageActiveView.getScreenDisplay()); ILegend legend = coerce(legendFrame.getMapSurround()); legend.setTitle("Map Legend."); legend.setAutoAdd(true); legend.refresh(); IElement mapElement = coerce(mapFrame); IEnvelope mainEnvelope = mapElement.getGeometry().getEnvelope(); IEnvelope elementEnvelope = coerce(new Envelope()); double xmin = mainEnvelope.getXMax() + 2; double ymin = mainEnvelope.getYMin() + 0.5; double xmax = mainEnvelope.getXMax() - 2; double ymax = mainEnvelope.getYMax() - 0.5; elementEnvelope.putCoords(xmin, ymin, xmax, ymax); legendElement.setGeometry((IGeometry)elementEnvelope); //add it to the graphicsContainer. graphicsContainer.addElement(legendElement, 0); //add a North Arrow IUID uidNorth = coerce(new UID()); uidNorth.setValue(MarkerNorthArrow.getClsid()); IEnvelope northArrowEnvelope = coerce(new Envelope()); northArrowEnvelope.putCoords(xmin , ymax - 0.5, xmin + 2, ymax + 1); IMapSurroundFrame northArrowFrame = mapFrame.createSurroundFrame(uidNorth, null); IElement northElement = coerce(northArrowFrame); northElement.setGeometry(northArrowEnvelope); graphicsContainer.addElement(northElement, 0); //add a Title TextElement title = new TextElement(); title.setSize(20); title.setText(serverObject.getConfigurationName().toUpperCase()); IPoint titleGeometry = coerce(new Point()); titleGeometry.setX((ymax - ymin) / 2); titleGeometry.setY(((xmin + xmax) / 2) + 2); IElement titleElement = coerce(title); titleElement.setGeometry(titleGeometry); //title element is always on top graphicsContainer.addElement(titleElement, 1); //Add a ScaleBar IUID uidScaleBar = coerce(new UID()); uidScaleBar.setValue(AlternatingScaleBar.getClsid()); IMapSurroundFrame scaleBarFrame = mapFrame.createSurroundFrame(uidScaleBar, null); IEnvelope scaleEnvelope = coerce(new Envelope()); scaleEnvelope.putCoords(1, 1, 3, 1.3); IElement scaleElement = coerce(scaleBarFrame); scaleElement.setGeometry(scaleEnvelope); //Scale bar on top. graphicsContainer.addElement(scaleElement, 1); graphicsContainer.reset(); activeView.partialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); pageActiveView.partialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); //Generate Layout IMapServerLayout mapLayout = coerce(serverObject); IImageDescription imageDesc = coerce(new ImageDescription()); IImageDisplay imageDisplay = coerce(new ImageDisplay()); imageDisplay.setDeviceResolution(dpi); imageDisplay.setWidth(width); imageDisplay.setHeight(height); IImageType iImageType = coerce(new ImageType()); iImageType.setFormat(esriImageFormat.esriImagePNG24); iImageType.setReturnType(esriImageReturnType.esriImageReturnURL); imageDesc.setDisplay(imageDisplay); imageDesc.setType(iImageType); ILayoutImage outputImage = mapLayout.exportLayout(mapLayout.getDefaultPageDescription(), imageDesc); //dont persist -> restore back to original state. graphicsContainer.deleteElement(legendElement); graphicsContainer.deleteElement(northElement); graphicsContainer.deleteElement(titleElement); graphicsContainer.deleteElement(scaleElement); graphicsContainer.reset(); outputUrl = outputImage.getURL(); logger.info("Generated Layout : " + outputImage.getURL()); }catch (Exception e) { logger.severe("Error generating page layout : " + e.getMessage()); throw e; } } /*public void generatePageLayout() { try { Map map = (Map) serverObject.getMap(serverObject.getDefaultMapName()); PageLayout pageLayout = (PageLayout) map.getPageLayout(); pageLayout.reset(); MapFrame mapFrame = (MapFrame) pageLayout.findFrame(map); // create a legend UID uid = new UID(); uid.setValue(Legend.getClsid()); MapSurroundFrame legendFrame = (MapSurroundFrame) mapFrame.createSurroundFrame(uid, null); legendFrame.getMapSurround().setName("Map Legend"); legendFrame.activate(pageLayout.getScreenDisplay()); Legend legend = (Legend) legendFrame.getMapSurround(); legend.setTitle("Map Legend."); legend.setAutoAdd(true); legend.refresh(); legendFrame.setMapSurroundByRef(legend);//added by Ajit Envelope mainEnvelope = (Envelope) mapFrame.getGeometry().getEnvelope(); Envelope elementEnvelope = new Envelope(); double xmin = mainEnvelope.getXMax() + 2; double ymin = mainEnvelope.getYMin() + 0.5; double xmax = mainEnvelope.getXMax() - 2; double ymax = mainEnvelope.getYMax() - 0.5; elementEnvelope.putCoords(xmin, ymin, xmax, ymax); legendFrame.setGeometry(elementEnvelope); // add it to the pagelayout. pageLayout.addElement(legendFrame, 0); // add a North Arrow UID uidNorth = new UID(); uidNorth.setValue(MarkerNorthArrow.getClsid()); Envelope northArrowEnvelope = new Envelope(); northArrowEnvelope.putCoords(xmin, ymax - 0.5, xmin + 2, ymax + 1); MapSurroundFrame northArrowFrame = (MapSurroundFrame) mapFrame.createSurroundFrame(uidNorth, null); northArrowFrame.setGeometry(northArrowEnvelope); pageLayout.addElement(northArrowFrame, 0); // add a Title TextElement title = new TextElement(); title.setSize(20); title.setText("USA Map Service."); Point titleGeometry = new Point(); titleGeometry.setX((ymax - ymin) / 2); titleGeometry.setY(((xmin + xmax) / 2) + 2); title.setGeometry(titleGeometry); // title element is always on top pageLayout.addElement(title, 1); // Add a ScaleBar UID uidScaleBar = new UID(); uidScaleBar.setValue(AlternatingScaleBar.getClsid()); MapSurroundFrame scaleBarFrame = (MapSurroundFrame) mapFrame.createSurroundFrame(uidScaleBar, null); Envelope scaleEnvelope = new Envelope(); scaleEnvelope.putCoords(1, 1, 3, 1.3); scaleBarFrame.setGeometry(scaleEnvelope); // Scale bar on top. pageLayout.addElement(scaleBarFrame, 1); pageLayout.reset(); map.partialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); pageLayout.partialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); // Generate Layout // IMapServerLayout mapLayout = Macros.coerce(serverObject); ImageDescription imageDesc = new ImageDescription(); ImageDisplay imageDisplay = new ImageDisplay(); imageDisplay.setDeviceResolution(dpi); imageDisplay.setWidth(width); imageDisplay.setHeight(height); ImageType iImageType = new ImageType(); iImageType.setFormat(esriImageFormat.esriImagePNG24); iImageType.setReturnType(esriImageReturnType.esriImageReturnURL); imageDesc.setDisplay(imageDisplay); imageDesc.setType(iImageType); ILayoutImage outputImage = serverObject.exportLayout(serverObject.getDefaultPageDescription(), imageDesc); // dont persist -> restore back to original state. pageLayout.deleteElement(legendFrame); pageLayout.deleteElement(northArrowFrame); pageLayout.deleteElement(title); pageLayout.deleteElement(scaleBarFrame); pageLayout.reset(); outputUrl = outputImage.getURL(); logger.info("Generated Layout : " + outputImage.getURL()); } catch (AutomationException e) { logger.info("MapLayoutImpl exception: " + e.getMessage() + " - " + e.getDescription()); e.printStackTrace(); } catch (UnknownHostException e) { logger.info("MapLayoutImpl exception: " + e.getMessage() + " - " + e.getLocalizedMessage()); e.printStackTrace(); } catch (IOException e) { logger.info("MapLayoutImpl exception: " + e.getMessage() + " - " + e.getLocalizedMessage()); e.printStackTrace(); } }*/ public String getOutputUrl() { return outputUrl; } // This method is a convinience method to avoid all those interface type casts. @SuppressWarnings("unchecked") privateT coerce(F from) { return (T) from; } @SuppressWarnings("unused") private boolean isEmpty(String str) { if (str == null || str.length() == 0) { return true; } else { return false; } }}
PageLayoutSOE.java
/* Copyright 2010 ESRI* * All rights reserved under the copyright laws of the United States* and applicable international laws, treaties, and conventions.* * You may freely redistribute and use this sample code, with or* without modification, provided you include the original copyright* notice and use restrictions.* * See the use restrictions at <your ArcGIS install location>/DeveloperKit10.0/userestrictions.txt.* */package arcgissamples.soe;import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import java.util.Set;import com.esri.arcgis.carto.MapServer;import com.esri.arcgis.interop.AutomationException;import com.esri.arcgis.interop.extn.ArcGISExtension;import com.esri.arcgis.server.IServerObjectExtension;import com.esri.arcgis.server.IServerObjectHelper;import com.esri.arcgis.system.ILog;import com.esri.arcgis.system.ServerUtilities;import static com.esri.arcgis.system.ServerUtilities.*;import com.esri.arcgis.interop.extn.ServerObjectExtProperties;import com.esri.arcgis.system.IRESTRequestHandler;import com.esri.arcgis.server.json.*;@ArcGISExtension@ServerObjectExtProperties( displayName = "PageLayout SOE", description = "Presents the pagelayout view of layers in associated map service, alongwith with scale bar, north arrow, legend", supportsMSD = true) public class PageLayoutSOE implements IServerObjectExtension, IRESTRequestHandler{ private static final long serialVersionUID = 1L; private IServerObjectHelper soHelper; private ILog serverLog; private MapServer mapServer; public PageLayoutSOE() throws Exception { super(); } /**************************************************************************************************************************** * IServerObjectExtension methods: This is a mandatory interface that must be supported by all SOEs. This interface * is used by the Server Object to manage the lifetime of the SOE and includes two methods: init() and shutdown(). * The Server Object cocreates the SOE and calls the init() method handing it a back reference to the Server Object * via the Server Object Helper argument. The Server Object Helper implements a weak reference on the Server Object. * The extension can keep a strong reference on the Server Object Helper (for example, in a member variable) but * should not keep a strong reference on the Server Object. The log entries are merely informative and completely * optional. ****************************************************************************************************************************/ /** * init() is called once, when the instance of the SOE is created. */ public void init(IServerObjectHelper soh) throws IOException, AutomationException { /* * An SOE should get the Server Object from the Server Object Helper in order to make any method calls on the * Server Object and release the reference after making the method calls. */ this.soHelper = soh; this.serverLog = getServerLogger(); // get the Server Object (SO) this SOE is associated with this.mapServer = (MapServer) soHelper.getServerObject(); } /** * shutdown() is called once when the Server Object's context is being shut down and is about to go away. */ public void shutdown() throws IOException, AutomationException { /* * The SOE should release its reference on the Server Object Helper. */ this.mapServer = null; this.soHelper = null; this.serverLog = null; } /**************************************************************************************************************************** * IRESTRequestHandler methods: This interface indicates that SOE supports REST. It exposes two methods: handleRESTRequest() * and getSchema(). ****************************************************************************************************************************/ /** * Handles REST request */ public byte[] handleRESTRequest(String capabilities, String resourceName, String operationName, String operationInput, String outputFormat, String requestProperties, String[] responseProperties) throws IOException, AutomationException { /* * This method handles REST requests by determining whether an operation * or resource has been invoked and then forwards the request to * appropriate methods. */ try { // if no operationName is specified send description of specified // resource if (operationName.length() == 0) { return getResource(resourceName); } else // invoke REST operation on specified resource { return invokeRESTOperation(capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, responseProperties); } } catch (Exception e) { return ServerUtilities.sendError(0, "Exception occurred: " + e.getMessage(), null).getBytes("utf-8"); } } /** * Returns schema of the REST resource */ public String getSchema() throws IOException, AutomationException { try { JSONObject _PageLayoutSOE = createResource( "PageLayoutSOE", "Presents a page layout view of layers in associated map service, alongwith with scale bar, north arrow and legend", false); JSONArray _PageLayoutSOE_OpArray = new JSONArray(); _PageLayoutSOE_OpArray.put(createOperation("getPageLayoutBySize", "width, height, dpi", "json, html")); _PageLayoutSOE.put("operations", _PageLayoutSOE_OpArray); JSONArray _PageLayoutSOE_SubResourceArray = new JSONArray(); JSONObject layout1024x768 = createResource("PageLayout1024x768", "Page layout view of map of dimensions 1024 x 768", false); _PageLayoutSOE_SubResourceArray.put(layout1024x768); _PageLayoutSOE.put("resources", _PageLayoutSOE_SubResourceArray); return _PageLayoutSOE.toString(); } catch (JSONException e) { e.printStackTrace(); } return null; } /**************************************************************************************************************************** * SOE Util methods. ****************************************************************************************************************************/ /** * Invokes specified REST operation on specified REST resource * @param capabilitiesList * @param resourceName * @param operationName * @param operationInput * @param outputFormat * @param requestProperties * @param responseProperties * @return */ private byte[] invokeRESTOperation(String capabilitiesList, String resourceName, String operationName, String operationInput, String outputFormat, String requestProperties, String[] responseProperties) throws Exception { byte[] operationOutput = null; JSONObject operationInputAsJSON = new JSONObject(operationInput); //parse request properties and create a map java.util.MaprequestPropertiesMap = new HashMap (); if (requestProperties != null && requestProperties.length() > 0) { JSONObject requestPropertiesJSON = new JSONObject(requestProperties); Iterator jsonKeys = requestPropertiesJSON.keys(); while (jsonKeys.hasNext()) { String key = jsonKeys.next(); requestPropertiesMap.put(key, requestPropertiesJSON.getString(key)); } } //create a Map to hold response properties java.util.Map responsePropertiesMap = new HashMap (); if (resourceName.equalsIgnoreCase("") || resourceName.length() == 0) { if (operationName.equalsIgnoreCase("getPageLayoutBySize")) { operationOutput = generateLayoutAndReturnURL(mapServer, operationInputAsJSON).getBytes("utf-8"); } else { operationOutput = sendError(0, "Operation " + "\"" + operationName + "\" not supported on resource " + resourceName + ".", new String[]{"No other details", " specified"}).getBytes("utf-8"); } } else //if non existent sub-resource specified, report error { operationOutput = sendError(0, "No sub-resource by name \"" + resourceName + "\" found.", new String[]{""}).getBytes("utf-8"); } //convert response properties to String array if (!responsePropertiesMap.isEmpty()) { Set keys = responsePropertiesMap.keySet(); Iterator keysIterator = keys.iterator(); int i = 0; while (keysIterator.hasNext()) { String key = keysIterator.next(); String value = responsePropertiesMap.get(key); responseProperties[i] = key + "=" + value; i++; } } return operationOutput; } /** * Returns description of resource specified by resourceName * @param resourceName * @return byte[] */ private byte[] getResource(String resourceName) { try { if(resourceName.equalsIgnoreCase("") || resourceName.length() == 0) { //this.serverLog.addMessage(1, 8000, "1"); return getRootResourceDescription().toString().getBytes(); } if(resourceName.equalsIgnoreCase("PageLayout1024x768")) { JSONObject json = new JSONObject(); json.put("height", 1024); json.put("width", 768); json.put("dpi", 72); return generateLayoutAndReturnURL(mapServer, json).getBytes("utf-8"); } } catch (Exception e) { e.printStackTrace(); } return null; } /** * Returns description of the root resource * @return description as a JSONObject */ private JSONObject getRootResourceDescription() { try { JSONObject rootResource = new JSONObject(); rootResource.put("Name", "PageLayout SOE"); rootResource.put("Description", "Presents a Map's image in page layout format."); return rootResource; } catch (Exception e) { e.printStackTrace(); } return null; } /** * Generates PageLayout image and returns URL to the image * @param serverObject * @param width * @param height * @param dpi * @return Image URL as String */ private String generateLayoutAndReturnURL(MapServer serverObject, JSONObject inputParameters) { try { int height = inputParameters.getInt("height"); int width = inputParameters.getInt("width"); int dpi = inputParameters.getInt("dpi"); if ((height <= 0) || (width <= 0) || (dpi <= 0)) { return sendError(400, "Invalid Input.", null); } // generate page layout. PageLayoutImpl impl = new PageLayoutImpl(mapServer, width, height, dpi); impl.generatePageLayout(); this.serverLog.addMessage(1, 8000, "Layout Output : " + impl.getOutputUrl()); // set response properties JSONObject response = new JSONObject(); response.put("outputUrl", impl.getOutputUrl()); return response.toString(); } catch (Exception e) { return sendError(1, e.getMessage(), null); } } /**************************************************************************************************************************** * General Util methods. ****************************************************************************************************************************/ /** * Creates a REST resource based on specified name, description and collection flag * @param name * @param description * @param isCollection * @return REST resource as a JSONObject */ private JSONObject createResource(String name, String description, boolean isCollection) { try { JSONObject json = new JSONObject(); if (name.length() > 0 && name != null) { json.put("name", name); } else { throw new Exception("Resource must have a valid name."); } json.put("description", description); json.put("isCollection", isCollection); return json; } catch (Exception e) { e.printStackTrace(); } return null; } /** * Creates an operation that can be called on a REST resource, using specified name, parameter list and * output formats list * @param operationName * @param parameterList * @param supportedOutputFormatsList * @return Operation as a JSONObject */ private JSONObject createOperation(String operationName, String parameterList, String supportedOutputFormatsList) { try { JSONObject operation = new JSONObject(); if (operationName.length() > 0 && operationName != null) { operation.put("name", operationName); } else { throw new Exception("Operation must have a valid name."); } // parameters if (parameterList.length() > 0 && parameterList != null) { JSONArray operationParamArray = new JSONArray(); String[] parameters = parameterList.split(","); for (String parameter : parameters) { operationParamArray.put(parameter.trim()); } operation.put("parameters", operationParamArray); } else { throw new Exception( "Operation must have parameters. If your operation does not requires params, then please convert it to a sub-resource."); } // supported Output formats if (supportedOutputFormatsList.length() > 0 && supportedOutputFormatsList != null) { JSONArray outputFormatsArray = new JSONArray(); String[] outputFormats = supportedOutputFormatsList.split(","); for (String outputFormat : outputFormats) { outputFormatsArray.put(outputFormat.trim()); } operation.put("supportedOutputFormats", outputFormatsArray); } else { throw new Exception("Operation must have supported output formats specified"); } return operation; } catch (Exception e) { e.printStackTrace(); } return null; } /** * Returns a detailed error thats constructed based on specified code, message and details array. * @param code * @param message * @param details * @return error String */ private String sendError(int code, String message, String[] details) { /* * An json error is sent back to client in the following structure.{ "error": { "code": 400, "message": * "Cannot perform query. Invalid query parameters.", "details": ["'time' param is invalid"] }} */ try { JSONObject errorObject = new JSONObject(); JSONObject error = new JSONObject(); error.put("code", code); error.put("message", message); if (details != null) { JSONArray detailsArray = new JSONArray(); for (String detail : details) { detailsArray.put(detail); } error.put("details", detailsArray); } errorObject.put("warning", error); return errorObject.toString(); } catch (JSONException e) { e.printStackTrace(); } return null; }}
其中还有一个 rest 的java客户端,这个是单独运行的,和上面两个没啥关系。上面两个文件发布成 jar文件,放到java/lib/ext文件夹下面后部署SOE成功,并且添加到地图服务的 功能 上就可以使用了。比如就是portland的地图服务下面的扩展功能 SOE 是 PageLayoutSOE 了。其实这个SOE可以放到任何一个地图服务的扩展功能当中。
PageLayoutRESTClient.java
/* Copyright 2010 ESRI* * All rights reserved under the copyright laws of the United States* and applicable international laws, treaties, and conventions.* * You may freely redistribute and use this sample code, with or* without modification, provided you include the original copyright* notice and use restrictions.* * See the use restrictions at <your ArcGIS install location>/DeveloperKit10.0/userestrictions.txt.* */package arcgissamples.soe.restclient;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.ProtocolException;import java.net.URL;import sun.misc.BASE64Encoder;public class PageLayoutRESTClient{ private String serverName = ""; private String mapServiceName = ""; private String soeName = ""; private String userName = ""; private String password = ""; public PageLayoutRESTClient(String serverName, String mapServiceName, String soeName, String userName, String password) { this.serverName = serverName; this.mapServiceName = mapServiceName; this.soeName = soeName; this.userName = userName; this.password = password; } public static void main(String[] args) { String serverName = ""; String mapServiceName = ""; String soeName = ""; String userName = ""; String password = ""; if(args.length == 5) { serverName = args[0]; mapServiceName = args[1]; soeName = args[2]; userName = args[3]; password = args[4]; } else { System.out.println("Wrong Usage. For correct usage, see following: \n" + "\nUsage: PageLayoutRESTClient [server name] [map service name] [soe name] [user name] [password]\n\n" + "[server name] - Specifies name of ArcGIS Server\n" + "[map service name] - Specifies name of map service\n" + "[soe name] - Specifies SOE name\n" + "[username] - Specifies user name\n" + "[password] - Specifies user password\n"); System.exit(1); } try { PageLayoutRESTClient client = new PageLayoutRESTClient(serverName, mapServiceName, soeName, userName, password); client.consumeRESTSOE(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void consumeRESTSOE() throws MalformedURLException, IOException { //get SOE's JSON representation String url = "http://" + this.serverName + ":8399/arcgis/rest/services/" + this.mapServiceName + "/MapServer/exts/" + this.soeName + "?f=json"; System.out.println("\nSOE's JSON representation: \n" + sendReceive(url)); //invoke sub resource url = "http://" + this.serverName + ":8399/arcgis/rest/services/" + this.mapServiceName + "/MapServer/exts/" + this.soeName + "/PageLayout1024x768?f=json"; System.out.println("\nSub Resource: \n" + sendReceive(url)); //invoke operation url = "http://" + this.serverName + ":8399/arcgis/rest/services/" + this.mapServiceName + "/MapServer/exts/" + this.soeName + "/getPageLayoutBySize?" + "width=1024&height=800&dpi=72&f=json"; System.out.println("\nOperation: \n" + sendReceive(url)); } private String sendReceive(String urlString) throws MalformedURLException, IOException { //create HTTP connection URL url = new URL(urlString); HttpURLConnection httpConnection = getHTTPConnection(url, "GET", this.userName, this.password); System.out.println("Header Info: \n"); printHTTPHeaderInfo(httpConnection); //send request httpConnection.connect(); //get response String response = getResponse(httpConnection); //disconnect httpConnection.disconnect(); return response; } /** * Prints HTTP Header info * @param httpConnection */ private void printHTTPHeaderInfo(HttpURLConnection httpConnection) { // look at headers // the 0th header has a null key, and the value is the response line ("HTTP/1.1 200 OK" or whatever) String header = null; String headerValue = null; int index = 0; while ((headerValue = httpConnection.getHeaderField(index)) != null) { header = httpConnection.getHeaderFieldKey(index); if (header == null) System.out.println(headerValue); else System.out.println(header + ": " + headerValue); index++; } } /** * Returns an HTTPURLConnection object based on specified URL and HTTP method, username and password * @param url * @param method * @return */ private HttpURLConnection getHTTPConnection(URL url, String httpMethod, String userName, String userPassword) { try { //boolean quiet, String httpMethod, URL url, String username, String password, InputStream body) HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection(); httpConnection.setRequestMethod(httpMethod); // write auth header BASE64Encoder encoder = new BASE64Encoder(); String encodedCredential = encoder.encode( (userName + ":" + userPassword).getBytes() ); httpConnection.setRequestProperty("Authorization", "BASIC " + encodedCredential); return httpConnection; } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Returns response from an HTTPConnection object * @param httpConnection * @return */ private String getResponse(HttpURLConnection httpConnection) { try { InputStream responseBodyStream = httpConnection.getInputStream(); StringBuffer responseBody = new StringBuffer(); int read = 0; byte buffer[] = new byte[8192]; while ((read = responseBodyStream.read(buffer)) != -1) { responseBody.append(new String(buffer, 0, read)); } responseBody.trimToSize(); return responseBody.toString(); } catch (IOException e) { e.printStackTrace(); } return null; } }
对于客户端 纯java程序,不解释了。SOE文件,其主要就是实现两个接口的方法: IServerObjectExtension, IRESTRequestHandler的。一个是SOE的主要接口,一个是rest服务的接口,当然后者也可以为soap的服务接口。
arcgis plugin for eclipse的创建SOE扩展的时候有一点需要注意:一定要有一个操作,否则生成的代码有点错误 。关于SOE研究下init shutdown方法和 handleRESTRequest getSchema invokeRESTOperation方法就可以,其他方法都是辅助这些方法的。
此SOE的操作其实是调用了 PageLayoutImpl impl = new PageLayoutImpl(mapServer, width, height, dpi);
impl.generatePageLayout();
impl.getOutputUrl();
三个方法。下面就是关键的PageLayoutImpl.java类了。也主要就是这三个方法。此方法最重要的是 SOE 传递了MapServer mapServer参数,以及三个选项参数。
此SOE的代码太乱了,我精简下,把那些 什么指南针,图例,legend之类的图片上的文字全部去掉,其代码就是:
public void generatePageLayout() throws Exception { try { //Generate Layout IMapServerLayout mapLayout = coerce(serverObject); IImageDisplay imageDisplay = coerce(new ImageDisplay()); imageDisplay.setDeviceResolution(dpi); imageDisplay.setWidth(width); imageDisplay.setHeight(height); IImageType iImageType =(new ImageType());//coerce(new ImageType()); iImageType.setFormat(esriImageFormat.esriImagePNG24); iImageType.setReturnType(esriImageReturnType.esriImageReturnURL); IImageDescription imageDesc = coerce(new ImageDescription()); imageDesc.setDisplay(imageDisplay); imageDesc.setType(iImageType); //核心啊 exportLayout就生成了缓存的图片(此缓存图片会在一定时间后自动删除) ILayoutImage outputImage = mapLayout.exportLayout(mapLayout.getDefaultPageDescription(), imageDesc); //缓存图片的连接示例为: this.outputUrl = outputImage.getURL(); logger.info("Generated Layout : " + outputImage.getURL()); }catch (Exception e) { logger.severe("Error generating page layout : " + e.getMessage());//这个是SOE的日志 throw e; } }
生成的图片干净了许多,但是我现在想要生成 要素 的透明png图片,可不是layout了。如何生成呢?伤脑筋那。