Querying Image Service's raster table

4119
2
Jump to solution
06-02-2016 11:39 AM
JoanneMcGraw
Frequent Contributor


I am working with ArcGIS Server and Desktop 10.4 and creating an application using the JSAPI 3.16.

I have a TIF that has an attribute table associated with it. I am trying to publish this image as an ArcGIS Server service that I will be able to query; e.g., return records where 'field1'=1 and 'field2'=2. There are a number of fields and an example of the previous query might return anywhere from none to a couple hundred pixel values which could have any number of pixel counts associated with them in the raster itself. The idea is to use a ColorMap to display the 5 - 10 most prevalent combinations in a Map object.

  • I've tried sharing the tif as an image service but don't seem to get access to the query functionality (using the URL to .../ImageServer/query). I am told 'Requested operation is not supported by this service.'
  • I've tried publishing a RasterDataset but, again, don't get access to the query functionality.
  • I've tried creating a map service with the tif and publishing that as a map service, but couldn't seem to get at the attribute data. There were no fields showing up for that layer in the map service definition.
  • I've tried creating a mosaic dataset and, although I finally have access to the query functionality for the Image Service, I can only query the mosaic dataset's table, not the contents of the image itself.
  • I looked into using a RasterDataSource in JavaScript but couldn't get it working and couldn't find an example.

So, I guess my first question is...is what I am trying to do even possible? And, if so, can someone tell me the basic combination of things I should be putting together to achieve it?

At the moment, I can get what I need to work if I create a second ArcGIS Service from a fake point layer that I made where every point is at 0,0 and each record is basically just the same attributes as the raster attribute table. I can certainly query that, but I don't want two copies of essentially the same information on the server because they could become inconsistent if the raster data is updated. Also, I don't want to waste resources running a second service that's only there so I can query what I feel like I should be able to get at somehow through the image service itself...if only I knew how.

Any pointers anyone can offer are appreciated.

Cheers,

jtm

0 Kudos
1 Solution

Accepted Solutions
JoanneMcGraw
Frequent Contributor

So, I finally contacted ESRI Support about this one and received the following response (after a few back and forths for clarification):

Unfortunately, we couldn't find an out-of-the-box way to do this.
I wanted to discuss your options, which are mainly:
- GP service
- SOE
- Separate web service
- Client-side querying

We had a further discussion re: those options over the phone. For various reasons (e.g., performance at runtime is inadequate using a GP service or doingclient-side querying because the tables involved are huge and it would take to long to transfer their entire content), we basically came down to the realization that what I was doing, as a general approach, was probably the best we could do.

However, because I didn't want to have two services running for every one of the rasters involved, I did make one alteration to my design. I create a MapService with a File Geodatabase dynamic workspace that I use to simply access copies of the raster attribute tables that I have placed in there.

Basically, I do something like this:

            var strLayer = JSON.stringify(
                {
                    "source":{
                        "type": "dataLayer",
                        "dataSource": {
                            "type": "table",
                            "workspaceId":"cr_rc",
                            "dataSourceName": "crop_rotations_table"
                        }
                    }
                }
            );


            var queryTask = esri.request(
                {
                    url: "http://<domain>/atlas/rest/services/dynWS/MapServer/dynamicLayer/query"
                    ,handleAs: "json"
                    ,callbackParamName: "callback"
                    ,content:{
                        f:"json"
                        ,layer: strLayer
                        ,where: "\"CODE2011\"=167 AND \"CODE2012\"=147"
                        ,outFields: "VALUE, COUNT, CROP2011, CROP2012, CROP2013, CROP2014"
                        ,orderByFields: "COUNT DESC"
                    }
                }
            );
            queryTask.then(
                function(response){
                    if (response.features && response.features.length > 0){
                         // doSomething
                    }
                    else {
                        console.log("No features returned");
                    }
                }
                ,function(error){
                    console.log("Error: " + error);
                }
            );

Just adding this info in case someone else goes looking.

Cheers,

jtm

View solution in original post

2 Replies
JoanneMcGraw
Frequent Contributor

I'm continuing to look into this problem and this is why I believe that what I am trying to do is possible.

I see the following text on this web page: Image service layer properties—Help | ArcGIS for Desktop

Definition Query tab

The Definition Query tab allows you to build a query to define a subset of a raster dataset that will be displayed in the image service. This tab is present when the image service contains multiple images and fields that can be queried. You can use Query Builder to build a query using a Structured Query Language (SQL) expression.

So..."when the image service contains multiple images and fields that can be queried" is this telling me that I have to use a mosaic dataset...to get multiple images in to the service? If so, that's fine. But, every way I've tried to get this TIF (and I've tried adding a second TIF with similar data just to get "multiple" images in there) into a mosaic dataset it only lets me query against the standard mosaic attribute table which has two entries. It doesn't let me query the data that's actually associated with the pixel values in the images themselves.

Is there some trick to adding the rasters to the mosaic dataset so that I can get at the raster attribute tables' data?

I tried adding a TIF as a "Table", but that operation just fails (not surprisingly).

Any clues as to general approach would be welcome.

Cheers,

jtm

0 Kudos
JoanneMcGraw
Frequent Contributor

So, I finally contacted ESRI Support about this one and received the following response (after a few back and forths for clarification):

Unfortunately, we couldn't find an out-of-the-box way to do this.
I wanted to discuss your options, which are mainly:
- GP service
- SOE
- Separate web service
- Client-side querying

We had a further discussion re: those options over the phone. For various reasons (e.g., performance at runtime is inadequate using a GP service or doingclient-side querying because the tables involved are huge and it would take to long to transfer their entire content), we basically came down to the realization that what I was doing, as a general approach, was probably the best we could do.

However, because I didn't want to have two services running for every one of the rasters involved, I did make one alteration to my design. I create a MapService with a File Geodatabase dynamic workspace that I use to simply access copies of the raster attribute tables that I have placed in there.

Basically, I do something like this:

            var strLayer = JSON.stringify(
                {
                    "source":{
                        "type": "dataLayer",
                        "dataSource": {
                            "type": "table",
                            "workspaceId":"cr_rc",
                            "dataSourceName": "crop_rotations_table"
                        }
                    }
                }
            );


            var queryTask = esri.request(
                {
                    url: "http://<domain>/atlas/rest/services/dynWS/MapServer/dynamicLayer/query"
                    ,handleAs: "json"
                    ,callbackParamName: "callback"
                    ,content:{
                        f:"json"
                        ,layer: strLayer
                        ,where: "\"CODE2011\"=167 AND \"CODE2012\"=147"
                        ,outFields: "VALUE, COUNT, CROP2011, CROP2012, CROP2013, CROP2014"
                        ,orderByFields: "COUNT DESC"
                    }
                }
            );
            queryTask.then(
                function(response){
                    if (response.features && response.features.length > 0){
                         // doSomething
                    }
                    else {
                        console.log("No features returned");
                    }
                }
                ,function(error){
                    console.log("Error: " + error);
                }
            );

Just adding this info in case someone else goes looking.

Cheers,

jtm