Extending a Resource |
Here is an example of extending the spatial analysis function to implement a special buffer analysis function, which is used to get the buffer of the desired line L1. The coordinates of the endpoints of L1 are: (116.40, 39.97), (116.40, 40.00), and (116.38, 40.00).
The resource <root_uri>/spatialanalyst/geometry/mybuffer is implemented, and a POST request is performed on the resource to implement the buffer analysis. The request body parameter is designed as a Double number, indicating the buffer radius. The analysis result is the round head buffer of L1.
Note: The analysis result is saved in the storage repository provided by iServer SDK as the child resource of the mybuffer resource. It can be got by performing a GET request on <root_uri>/spatialanalyst/geometry/mybuffer/{id}.
As to the extension of resources support the POST request, it is recommended to use the base class com.supermap.services.rest.resources.JaxAlgorithResultSetResource provided by SuperMap iServer for extension.
Please see the sample code: %SuperMap iServer Java_HOME%\samples\code\ExtendExist_JSR\MyBufferResultsResource.java.
The type of the request body parameter of the POST request is double. Compose a MyBufferResultsResource class as follows:
@Path("/spatialanalyst/geometry/mybuffer")
public class MyBufferResultsResource extends JaxAlgorithResultSetResource<Double> {
……
}
@Path specifies the URI of mybuffer resource. In iServer6R, the root directory of the REST resource implemented based on the JAX-RS framework is: http://<server>:<port>/iserver/services/<servicecomponent>/<serviceinterface>, where servicecomponent is the service component, serviceinterface is the service interface (see Setting the Service URI), and restjsr is the default JAX-RS REST service interface. The example is expected to extend the spatial analysis function, and the spatial analysis service component is used.
Implement the abstract method as shown below:
/**
* The algorithm name, used for accessing the algorithm result.
*/
protected String getAlgorithmName() {
return "MyBuffer";
}
/**
* Implement the runArithmetic of the parent class. The business logic to be processed when the client sends the HTTP POST method.
* The Post method of the parent class will call the interface.
*/
protected Object runArithmetic(Double leftBufferDistance) {
//Construct buffer analysis parameters. The left buffer radius is leftBufferDistance, the right buffer radius is identical to left buffer radius, and the buffer type is ROUND
BufferAnalystParameter bufferParameter = this.createGeometryBufferPostParameter(leftBufferDistance);
//Construct the line geometry object as source for creating the buffer. The endpoints are (116.40, 39.97), (116.40, 40.00) and (116.38, 40.00).
Geometry sourceGeometry = this.createSourceGeometry();
// Get the business component for the buffer analysis.
SpatialAnalyst spatialAnalyst = null;
//Get all spatial analysis business components from the interface context.
List<SpatialAnalyst> spatialAnalystList = this.getInterfaceContext().getComponents(SpatialAnalyst.class);
//By default, there is only one spatial analysis business component in the interface context.
//There will be one business component in the interface context if the business component is bound to the REST interface.
//There will be zero or multiple spatial analysis business components in the interface context if the business component collection is bound to the REST interface.
spatialAnalyst = spatialAnalystList.get(0);
// Buffer analysis
return spatialAnalyst.buffer(sourceGeometry, bufferParameter, new GeometrySpatialAnalystResultSetting()).resultGeometry;
}
createGeometryBufferPostParameter and createSourceGeometry are the creation parameters and the code is as follows:
Code
The service component is got from the service interface context. In order to get the correct service interface component, it needs to inherit the constructor of the parent class (JaxAlgorithResultSetResource):
/**
* The constructor of the resource implementation class.
* The parameters of servletConfig and httpRequest will be injected dynamically when processing the request by the Jax-rs runtime.
* @param servletConfig The unique global Servlet configuration
*/
public MyBufferResultsResource(@Context ServletConfig servletConfig) {
// If the spatial analysis business component is expected to get from the resource, the corresponding constructor of the parent class should be overloaded.
super(servletConfig);
}
The POST request is usually used to create a child resource, and here a buffer analysis result resource is created. In order to get the algorithm resource, a child resource supporting the GET method is implemented in MyBufferResultsResource.
/**
* Returns the specified analysis result.
* @param id The ID of the analysis result.
* @return The region buffer.
*/
@GET
@Path("{id}")
public Geometry getBufferResultGeometry(@PathParam("id") String id) {
// Get the object storage repository, where the buffer analysis result is stored.
// There are multiple child repositories in this repository, differentiated by the key value. Here the key value is MyBuffer.
TempObjRepository objRepository = this.getRepository();
return (Geometry) objRepository.getArithResult(ALGORITHNAME, id);
}
Where @GET represents that this method corresponds to the GET request, @Path ("{id}") is the URI of the results resource, here, from the URI of the mybuffer resource. {id} corresponds to @PathParam("id") String id, indicateing passing the URI {id} to String id. If the GET request URI is <mybuffer_uri>/12, the analysis result with the ID of 12 will be got.
Up until now, the sample is finished. The parent resource <root_uri>/spatialanalyst/geometry/mybuffer supports the POST request. The response of the POST request will include the URIs of the child resources. The child resource <root_uri>/spatialanalyst/geometry/mybuffer/{id} supports the GET request.
Note: The @Template annotation is not supported here. By default, the HTTP output formats like xml, json and rjson are supported. The default message body format supported by mybuffer is JSON.
Create the MyBufferAnalystRest.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<resource>
<configID>mybuffer</configID>
<implementClass>com.supermap.sample.extend.MyBufferResultsResource</implementClass>
</resource>
</resources>
Create the JAX-RS resource configuration file. The example is the extension of the spatial analysis module. Therefore, the configuration file name should be consistent with that of the spatial analysis module configuration file, SpatialAnalystRest (See Table Module and Configuration), shown as below:
resourceFiles=MyBufferAnalystRest.xml
Create a jar package withe the configuration file and the compiled result of implementation class of the Mybuffer resource (see extendexist_jsr.jar), put it under %SuperMap iServer Java_HOME%/webapps/iserver/WEB-INF/libm and restart SuperMap iServer6R.
MyBufferAnalystRest.xml is located in Jar:///MyBufferAnalystRest.xml, and SpatialAnalystRest is located in Jar:///META-INF/extensions/services/rest/SpatialAnalystRest.
After restarting the server, http://localhost:8090/iserver/services/spatialanalyst-sample/restjsr is an existing spatial analysis module. Access the newly extended MyBuffer resource by implementing a POST request on http://localhost:8090/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst/geometry/mybuffer.rjsonl, and the request body is "4".
POST http://localhost:8090/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst/geometry/mybuffer.rjson HTTP/1.1
Content-Length: 1
Content-Type:application/json
4
The response in rjson format is as follows:
{
"newResourceID": "4",
"newResourceLocation": "http://localhost:8090/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst/geometry/mybuffer/1",
"postResultType": "CreateChild",
"succeed": true
}
Where newResourceLocation is the child resource (address of the algorithm result). Implement a GET request on http://localhost:8090/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst/geometry/mybuffer/1.rjson to get the response in rjson output format, as shown below.
{
"id": 0,
"parts": [11],
"points": [
{
"x": 112.38,
"y": 40
},
{
"x": 113.06183262486397,
"y": 37.76622174990826
},
{
"x": 115.86321759723121,
"y": 36.006180547492384
},
{
"x": 119.03181215029919,
"y": 36.95776415174084
},
{
"x": 120.4,
"y": 39.97
},
{
"x": 120.4,
"y": 40
},
{
"x": 119.22842712474619,
"y": 42.82842712474619
},
{
"x": 116.4,
"y": 44
},
{
"x": 116.38,
"y": 44
},
{
"x": 113.55157287525381,
"y": 42.82842712474619
},
{
"x": 112.38,
"y": 40
}
],
"style": null,
"type": "REGION"
}
The result is a region object (com.supermap.services.components.commontypes.Geometry).