Changes between Version 7 and Version 8 of ZooWorkshop/FOSS4GJapan/CreatingOGRBasedWebServices

Oct 15, 2010, 5:52:16 PM (11 years ago)



  • ZooWorkshop/FOSS4GJapan/CreatingOGRBasedWebServices

    v7 v8  
    150150=== Boundary ===
    152 ==== C Version ====
     152=== C Version ===
    154154As explained before, ZOO Kernel will pass the parameters to your Service function in a specific datatype called maps. In order to code your Service in C language, you also need to learn how to access this datatype in read/write mode.
    428428Your ZOO Services Provider is now ready to use from an Execute request passed to ZOO Kernel.
    430 ==== Python Version ====
     430=== Python Version ===
     432For those using Python to implement their ZOO Services Provider, the full code to copy in in cgi-env directory is shown bellow. Indeed, as Python is an interpreted language, you do not have to compile anything before deploying your service which makes the deployement step much easier :
     436import osgeo.ogr
     437import libxml2
     439def createGeometryFromWFS(my_wfs_response):
     440    doc=libxml2.parseMemory(my_wfs_response,len(my_wfs_response))
     441    ctxt = doc.xpathNewContext()
     442    res=ctxt.xpathEval("/*/*/*/*/*[local-name()='Polygon' or local- name()='MultiPolygon']")
     443    for node in res:
     444        geometry_as_string=node.serialize()
     445        geometry=osgeo.ogr.CreateGeometryFromGML(geometry_as_string)
     446        return geometry
     447    return geometry
     449def Boundary(conf,inputs,outputs):
     450    if inputs["InputPolygon"]["mimeType"]=="application/json":
     451        geometry=osgeo.ogr.CreateGeometryFromJson(inputs["InputPolygon"]["value"])
     452    else:
     453        geometry=createGeometryFromWFS(inputs["InputPolygon"]["value"])
     454    rgeom=geometry.GetBoundary()
     455    if outputs["Result"]["mimeType"]=="application/json":
     456        outputs["Result"]["value"]=rgeom.ExportToJson()
     457        outputs["Result"]["mimeType"]="text/plain"
     458    else:
     459        outputs["Result"]["value"]=rgeom.ExportToGML()
     460    geometry.Destroy()
     461    rgeom.Destroy()
     462    return 3
     465We do not dicuss the functions body here as we already gave all the details before and the code was volontary made in a similar way.
     467As done before, you only have to copy the cgi-env files into your cgi-bin directory :
     471sudo cp ./cgi-env/* /usr/lib/cgi-bin
     474A simple Makefile containing the install section can be written as the following :
     478        sudo cp ./cgi-env/* /usr/lib/cgi-bin/
     481Finally, simply run make install from the ZOO Services Provider main directory, in order to deploy your ZOO Service Provider.
     483=== Testing the Service using Execute Request ===
     485==== The simple and unreadable way ====
     487Everybody should now get his own copy of the OGR Boundary Service stored as a ZOO Services Provider called ogr_ws_service_provider and deployed in the ZOO Kernel tree, so the following Execute request can be used to test the Service :
     489[http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Boundary&DataInputs=InputPolygon=Reference@xlink:href= http%3A%2F%2Flocalhost%3A8082%2Fgeoserver%2Fows%3FSERVICE%3DWFS%26REQUEST%3DGetFeature%26VERSION%3D1.0.0%26typename%3Dtopp%3Astates%26SRS%3DEPSG%3A4326%26FeatureID%3Dstates.15]
     491As you can see in the url above, we use an URLEncoded WFS request to the Geoserver WFS server available on OSGeoLive as a xlink:href key in the DataInputs KVP value, and set the InputPolygon value to Reference. The corresponding non encoded WFS request is as follow :
     493[http://localhost:8082/geoserver/ows/?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.0.0&typename=topp:states&SRS=EPSG:4326&FeatureID=state s.15]
     495Please note that you can add lineage=true to the previous request if you need to get information about the input values used to run your Service. Furthermore, you may need to store theExecuteResponse document of your ZOO Service to re-use it later. In this case you must addstoreExecuteResponse=true to the previous request. Note that is an important thing as the behavior of ZOO Kernel is not exactly the same than when running without this parameter settled to true. Indeed, in such a request, ZOO Kernel will give you an ExecuteResponse document which will contain the attribute statusLocation, which inform the client where the ongoing status or the final ExecuteResponse will be located.
     497Here is an example of what the ExecuteResponse using storeExecuteResponse=true in the request would look like :
     499Then, according to the statusLocation, you should get the ExecuteResponse as you get before using the previous request. Note that can be really useful to provide some caching system for a client application.
     501You didn't specify any ResponseForm in the previous request, it is not requested and should return a ResponseDocument per default using the application/json mimeType as you defined in you zcfg file. Nevertheless, you can tell ZOO Kernel what kind of data you want to get in result of your query adding the attribute mimeType=text/xml to your ResponseDocument parameter. Adding this parameter to the previous request will give us the result as its GML representation :
     503[http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Boundary&DataInputs=InputPolygon=Reference@xlink:href= http%3A%2F%2Flocalhost%3A8082%2Fgeoserver%2Fows%3FSERVICE%3DWFS%26REQUEST%3DGetFeature%26VERSION%3D1.0.0%26typename%3Dtopp%3Astates%26SRS%3DEPSG%3A4326%26FeatureID %3Dstates.15&ResponseDocument=Result@mimeType=text/xml]
     505As defined by the WPS specifications, you can also ask for a RawDataOutput to get only the data without the full ResponseDocument. To do that, you only have to replace the ResponseDocument of your request by RawDataOutput, like in the following request :
     507[http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Boundary&DataInputs=InputPolygon=Reference@xlink:href= http%3A%2F%2Flocalhost%3A8082%2Fgeoserver%2Fows%3FSERVICE%3DWFS%26REQUEST%3DGetFeature%26VERSION%3D1.0.0%26typename%3Dtopp%3Astates%26SRS%3DEPSG%3A4326%26FeatureID %3Dstates.15&RawDataOutput=Result@mimeType=application/json]
     509Finally, please note that we go back to the default mimeType to directly obtain the JSON string as we will use this kind of request to develop our client application in the next section of this workshop.
     511==== Simplification and readability of request ====
     513As you can see in the simple example we used since the begining of this workshop, it is sometimes hard to write the Execute requests using the GET method as it makes really long and complexe URLs. In the next requests examples, we will thus use the POST XML requests. First , here is the XML request corresponding to the previous Execute we used :
     517<wps:Execute service="WPS" version="1.0.0" xmlns:wps="" xmlns:ows="" xmlns:xlink="" xmlns:xsi="" xsi:schemaLocation=" ../wpsExecute_request.xsd">
     518 <ows:Identifier>Boundary</ows:Identifier>
     519 <wps:DataInputs>
     520  <wps:Input>
     521   <ows:Identifier>InputPolygon</ows:Identifier>
     522   <ows:Title>Playground area</ows:Title>
     523   <wps:Reference xlink:href="http://localhost:8082/geoserver/ows/?SERVICE=WFS&amp;REQUEST=GetFeature&amp;VERSION=1.0.0&amp;typename=topp:states&amp;SRS=EPSG:43 26&amp;FeatureID=states.15"/>
     524  </wps:Input>
     525 </wps:DataInputs>
     526 <wps:ResponseForm>
     527  <wps:ResponseDocument>
     528   <wps:Output>
     529    <ows:Identifier>Result</ows:Identifier>
     530    <ows:Title>Area serviced by playground.</ows:Title>
     531    <ows:Abstract>Area within which most users of this playground will live.</ows:Abstract>
     532   </wps:Output>
     533  </wps:ResponseDocument>
     534 </wps:ResponseForm>
     538In order to let you easily run the XML requests, a simple HTML form called test_services.html is available in your /var/www directory. You can access it using the following link : http://localhost/test_services.html.
     540Please open this page in your browser, simply fill the XML request content into the textarea field and click the « run using XML Request » submit button. You will get exactly the same result as when running your Service using the GET request. The screenshot above show the HTML form including the request and the ExecuteResponse document displayed in the iframe at the bottom of the page :
     542The xlink:href value is used in the simplest way to deal with such data input. Obviously, you can also use a full JSON string of the geometry, as shown in the following XML Request example :
     546<wps:Execute service="WPS" version="1.0.0" xmlns:wps="" xmlns:ows="" xmlns:xlink="" xmlns:xsi="" xsi:schemaLocation=" ../wpsExecute_request.xsda">
     547 <ows:Identifier>Boundary</ows:Identifier>
     548 <wps:DataInputs>
     549  <wps:Input>
     550   <ows:Identifier>InputPolygon</ows:Identifier>
     551   <wps:Data>
     552    <wps:ComplexData mimeType="application/json">
     553{ "type": "MultiPolygon", "coordinates": [ [ [ [ -105.998360, 31.393818 ], [ -106.212753, 31.478128 ], [ -106.383041, 31.733763 ], [ -106.538971, 31.786198 ], [ -106.614441, 31.817728 ], [ -105.769730, 31.170780 ], [ -105.998360, 31.393818 ] ] ], [ [ [ -94.913429, 29.257572 ], [ -94.767380, 29.342451 ], [ -94.748405, 29.319490 ], [ -95.105415, 29.096958 ], [ -94.913429, 29.257572 ] ] ] ] }
     554    </wps:ComplexData>
     555   </wps:Data>
     556  </wps:Input>
     557 </wps:DataInputs>
     558 <wps:ResponseForm>
     559  <wps:ResponseDocument>
     560   <wps:Output>
     561    <ows:Identifier>Result</ows:Identifier>
     562    <ows:Title>Area serviced by playground.</ows:Title>
     563    <ows:Abstract>Area within which most users of this playground will live.</ows:Abstract>
     564   </wps:Output>
     565  </wps:ResponseDocument>
     566 </wps:ResponseForm>
     570If everything went well, you should get the Boundary of the JSON geometry passed as argument, and so be sure that your Service support both GML and JSON as input data. Note that in the previous request, we added a mimeType attribute to the ComplexData node to specify that the input data is not in the default text/xml mimeType but passed as an application/json string directly. It is similar to add @mimeType=application/json as we discussed before.
     572== Creating Services for other functions (ConvexHull and Centroid) ==


Context Navigation

ZOO Sponsors

Become a sponsor !

Knowledge partners

Become a knowledge partner

Related links