Select to view content in your preferred language

Query using BlazeDS / WebService

788
4
11-22-2010 04:42 AM
Alexandervan_der_Schans
Emerging Contributor
Hi everybody,

I have a question about querying data using remote services. My maps exist on our ArcGIS server, but the data which is not geospatially enabled is coming from a MS SQL Server 2008, and now I am wondering what's the best way to perform a query that connects the two? ArcSDE is one possible way I suppose, but how do you handle data that comes in via Webservice calls or BlazeDS? I want to draw features based on data from the remote service. So a simple example would be if the data in a certain field is between numbers 1 and 2, the feature would turn green. Can anyone guide me to some examples on how to use blazeDS with ArcGIS, and how to query based on that data?  I have no experience in this area so any help would be greatly appreciated!

Thanks,
Alex
Tags (2)
0 Kudos
4 Replies
ReneRubalcava
Esri Frequent Contributor
Does the data in the tables you are querying via BlazeDS match fields in your map service?
For example, what I do is use BlazeDS/WebOrb to query various tables of land use and property information, get back a list of say parcel numbers, then I perform a QueryTask on the map service of parcels using those parcel numbers. For various reasons, this data sits outside an SDE, but I can use the remote service to tie everthing together.

I've gotten very comfortable working with my data in this manner and because I can customize the queries to my hearts content, I actually prefer it to Relationship queries provided by the ESRI Flex API.

For example, I have a java query in BlazeDS to queries some Flow data for our sewer system.

public static ArrayList<FlowControl> getFlowControlList() {
 ArrayList<FlowControl> flows = new ArrayList<FlowControl>();
 ResultSet resultSet;
 try {
  connection = ConnectionHelper.sdeConnection();
  Statement stmt = connection.createStatement();
  String sql = "SELECT CSDAssetID, CSDFeatureID, '' AS PipeCSDAssetID, '' AS PipeCSDFeatureID, UpstreamPipeCSDAssetID, UpstreamPipeCSDFeatureID, "
    + "DownstreamPipeCSDAssetID, DownstreamPipeCSDFeatureID, FlowControlInputDate, FlowAllowed, FlowControlPosition, Subtype "
    + "FROM sde.SSCOMPLEXFLOWCONTROLHISTORY AS cf "
    + "WHERE (FlowControlInputDate = "
    + "(SELECT MAX(FlowControlInputDate) AS Expr1 "
    + "FROM sde.SSCOMPLEXFLOWCONTROLHISTORY AS cf2 "
    + "WHERE (CSDAssetID = cf.CSDAssetID) AND (CSDFeatureID = cf.CSDFeatureID))) "
    + "UNION "
    + "SELECT CSDAssetID, CSDFeatureID, PipeCSDAssetID, PipeCSDFeatureID, '' AS UpstreamPipeCSDAssetID, '' AS UpstreamPipeCSDFeatureID, "
    + "'' AS DownstreamPipeCSDAssetID, '' AS DownstreamPipeCSDFeatureID, FlowControlInputDate, FlowAllowed, FlowControlPosition, Subtype "
    + "FROM sde.SSFLOWCONTROLHISTORY AS f "
    + "WHERE (FlowControlInputDate = "
    + "(SELECT MAX(FlowControlInputDate) AS Expr1 "
    + "FROM sde.SSFLOWCONTROLHISTORY AS f2 "
    + "WHERE (CSDAssetID = f.CSDAssetID) AND (CSDFeatureID = f.CSDFeatureID))) "
    + "ORDER BY CSDAssetID";
  resultSet = stmt.executeQuery(sql);

  while (resultSet.next()) {
   FlowControl flow = new FlowControl();
   flow.setCsdAssetId(resultSet.getString(CSD_ASSET_ID));
   flow.setCsdFeatureId(resultSet.getString("CSDFeatureID"));
   flow.setDownstreamPipeCsdAssetId(resultSet
     .getString("DownstreamPipeCSDAssetID"));
   flow.setDownstreamPipeCsdFeatureId(resultSet
     .getString("DownstreamPipeCSDFeatureID"));
   flow.setFlowAllowed(resultSet.getBoolean("FlowAllowed"));
   flow.setFlowControlInputDate(resultSet
     .getDate("FlowControlInputDate"));
   flow.setFlowControlPosition(resultSet
     .getString("FlowControlPosition"));
   flow.setPipeCsdAssetId(resultSet.getString("PipeCSDAssetID"));
   flow.setSubType(resultSet.getString("Subtype"));
   flow.setUpstreamPipeCsdAssetId(resultSet
     .getString("UpstreamPipeCSDAssetID"));
   flow.setUpstreamPipeCsdFeatureId(resultSet
     .getString("UpstreamPipeCSDFeatureID"));
   flows.add(flow);
   System.out.println("FlowList = " + flow.getCsdAssetId() + " : "
     + flow.getCsdFeatureId());
  } // end while statement

 } catch (SQLException ex) {

  System.out.println(ex.getMessage());

 } // end try-catch block

 finally {
  closeConnection();
 }
 return flows;
}


Then in my Flex project, I can use the ArrayList as a DataProvider for a table or iterate the list to build a query that will use an existing map service in my application.
0 Kudos
Alexandervan_der_Schans
Emerging Contributor
Yes, the data matches based on Unique identifiers. Your solution is actually one I am looking for, but I am not experienced in java programming. Would you say it is hard to pick up and learn or does it only take minimal java programming skills? From your example I dont quite understand though how the data returned from the java query enters Flex. Does the flex application communicate with blazeDS via the RemoteObject and how?
0 Kudos
ReneRubalcava
Esri Frequent Contributor
My java experience is pretty limited to just database access and queries. To access SQL Server, you'll need the sqljdbc4.jar from Microsoft. One thing I am doing in that query is turning my results into a custom object I call FlowControl, which is a pretty simple Java object, but what it allows me to do is quickly serialize those objects in Flex by adding this metadata tag to a class
[RemoteClass(alias="SewerDb.dto.FlowControl")]
public class FlowControl...

So your Flex object matches your Java object.
There are lots of materials on Adobe's website and elsewhere on using BlazeDS with Flex.
http://www.adobe.com/devnet/livecycle/articles/blazeds_spring.html

One book that I really like that just recently went into print is Flex On Java, which covers the subject really well.

If however, you are like me and prefer working in a .NET environment, you can use WebOrb for .NET, which is a great solution for tasks like this. A great benefit of WebOrb is the WebOrb console which will let you test your functions as well provide you the Actionscript code you would need to use the functions. It has fantastic code generation tools that you can use to learn from.

Using RemoteObjects requires slightly more setup initially to access backend data, but it absolutely worth it in the end. We have one function to perform flow tracing that can return a few thousand records that is done via a WebOrb AMF endpoint, and as a regular WSDL web service it took up to 2 minutes to return results and we can now show the query results in less than 10 seconds.
0 Kudos
Alexandervan_der_Schans
Emerging Contributor
Thanks Rene!

This will give me some good starting points. I will definetly check out the resources you posted, since I already felt that the blazeDS/webORB route might be the way to go for us. One last question though, how do set the color of the flowlines in your application? Do you just loop over the results from the query, and then bind the result to a ClassBreakRenderer? I don't know if there would be another way to do this.

thanks!
0 Kudos