1

What I am trying to achieve is to either filter an existing ArcGIS imageserver service, or get the results of a query and display them. The reason I want to do this is that I have a huge mosaic dataset and I want to display individual Map-Sheets (cause sometimes they even overlap).

By using this code I manage to connect to the service, query the desired image and get its attributes.

      IImageServer3 imageServer3 = (IImageServer3)GetImageServer("http://xxx.xxx.x.xxx:6080/arcgis/services", "ServiceFolder/Sample Service", false);

                IQueryFilter attFilter = new ImageQueryFilterClass();
                attFilter.WhereClause = "Name = '0212043980'";

                int count = imageServer3.GetCatalogItemCount(attFilter);
                MessageBox.Show(count.ToString());

With this I download the desired image and then I add it as a layer.

       var fff = imageServer3.GetCatalogItemIDs(attFilter);
                System.Net.WebClient webClient = new System.Net.WebClient();

IImageServerDownloadResults isDownloadResults = imageServer3.Download(fff, null, null); IImageServerDownloadResult isDownloadResult; string url, fileName; for (int i = 0; i < isDownloadResults.Count; i++) { isDownloadResult = isDownloadResults.get_Element(i); url = imageServer3.GetFile(isDownloadResult); fileName = "c:\\temp\\" + url.Substring(url.LastIndexOf("/") + 1); webClient.DownloadFile(url, fileName); }

But the thing is that I do not want to download the image (because most of the time the images are huge) I just want to display that single image it as a service.

I've done this in the past using the JavaScript web API, but I can't really understand if there is a way to do it on a desktop addin or not.

the reason I am doing this is that I want to create a custom user friendly search engine for a huge mosaic dataset

2

Just create a new instance of type MosaicRuleClass and assign it to your IImageServerLayer.

IImageServerLayer imageserverlayer = CreateSecuredISLayer(@"http://xxx.xxx.xxx:6080/arcgis/services", "Folder/mydata");

IMosaicRule mosaicRule = new MosaicRuleClass();
mosaicRule.MosaicMethod = esriMosaicMethod.esriMosaicLockRaster;
mosaicRule.LockRasterID = "615";
mosaicRule.MosaicOperatorType = rstMosaicOperatorType.MT_MAX;
IImageServerLayer3 isLayer = imageserverlayer as IImageServerLayer3;
isLayer.MosaicRule = mosaicRule;

ArcMap.Document.FocusMap.AddLayer(imageserverlayer);

Set the LockRasterID with the selected OID of your raster. That's all

  • This is indeed a neat solution but for some reason it does not work on Cached Mosaic Datasets. It gives a Catastrophic Failure error, which is indeed weird cause in a non-cashed dataset I tried it, it does work. I cannot grasp the reason why though. – elasticrash Jun 1 '15 at 11:03
0

You have mentioned ,

I want just to display it as a service.

To display an image service, you should create an image layer and then you can add this layer to the map or show it in a list. Then the user can manually do analysis with Arcmap (Clip,Attribute or Spatial Query,...)

  • For services without authentication:
public static IImageServerLayer AccessImageServerLayer(string agsUrl="http://server/arcgis/services/serviceName/imageserver")
{
    //Create an image server layer by passing a URL.
    IImageServerLayer imageserverlayer = new ImageServerLayerClass(); 
    imageserverlayer.Initialize(agsUrl); 
    return imageserverlayer;
}
  • For services that require https/authentication, use the following
IImageServerLayer imageserverlayer = CreateSecuredISLayer(@"http://server:6080/arcgis/services", "serviceName");

private static IImageServerLayer CreateSecuredISLayer(string agsUrl, string serviceName)
{
    IName soname = GetImageServerName(agsUrl, serviceName);
    IImageServerLayer isLayer = new ImageServerLayerClass();
    IDataLayer data_islayer = (IDataLayer)isLayer;
    data_islayer.DataSourceName = soname;
    return isLayer;
}


private static IName GetImageServerName(string hostOrUrl, string serviceName)
{
    IPropertySet propSet = new PropertySetClass();
    propSet.SetProperty("url", hostOrUrl);
    propSet.SetProperty("ANONYMOUS", false);
    //don't hardcode user/password
    //propertySet.SetProperty("user", userName);
    //propertySet.SetProperty("password", password);
    IAGSServerConnectionName agsServerConnectName = new AGSServerConnectionNameClass
        ();
    agsServerConnectName.ConnectionProperties = propSet;
    IAGSServerObjectName agsSOName = new AGSServerObjectNameClass();
    agsSOName.AGSServerConnectionName = agsServerConnectName;
    agsSOName.Name = serviceName;
    agsSOName.Type = "ImageServer";
    return (IName)agsSOName;
}
  • I got multiple ImageServer Layers which all require tokens as an authentication, I got that part solved and I already display several of them. The problem is that from a couple of those I dont want to display the entire mosaic dataset but a single image within that mosaic dataset. – elasticrash May 25 '15 at 10:46
  • I thought it was pretty clear from the title Ill edit the post so as to be more clear – elasticrash May 25 '15 at 10:50
  • IMosaicRule interface defines the mosaic rule for mosaicking requested images on the fly. It contains a mosaic method, its parameters, and a mosaic operation. In general, a mosaic rule is used to specify (1) the selection of rasters to participate in the mosaic; (2) how the selected rasters are ordered; (3) how overlapping pixels at the same location are resolved. [Sample Code],(help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/…) Maybe this is what you are looking for! – Farid Cheraghi May 25 '15 at 11:34
  • the thing is that this returns a url with the image (I tried it and I do get the image successfully, when i paste the url in a browser), again (as far as I can understand) how can i add this as a layer without downloading the image. – elasticrash May 26 '15 at 10:57
0

After a couple of days I figured out a solution...I got no idea if its optimal...but it does exactly what I want...

    //GLOBAL
    static IEnvelope _envpoint = new EnvelopeClass();
    IImageServer3 _imageServer3 =
        (IImageServer3)
            GisHelper.GetImageServer("http://IP:6080/arcgis/services",
                "Folder/MosaicDataset", false);

    //CODE IN the FUNCTION
                string namestr = name.ToString();
                IQueryFilter attFilter = new ImageQueryFilterClass();
                attFilter.WhereClause = "Name = '" + namestr + "'";

                IRecordSet items = _imageServer3.GetCatalogItems(attFilter);

                ICursor pCursor = items.Table.Search(null, false);
                IRow pRow = pCursor.NextRow();
                List<string> valuecollection = new List<string>();
                while (pRow != null)
                {
                    var t = pRow.get_Value(1);
                    var ddd = ((IGeometry) t);
                    _envpoint = ddd.Envelope;
                    pRow = pCursor.NextRow();
                }

                 var twidth = 800;
                var bts = ExportMapImageUrl(_imageServer3, items, twidth);
                if (_envpoint != null)
                {
                Bitmap bitmapp;

                using (var ms = new MemoryStream(bts))
                {
                    bitmapp = new Bitmap(ms);
                }

For some reason it needs a path that you can read and write but it doesn't seem to use it in any way since the image is created on memory

                var commonappdata = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                var rasterds = CreateRasterDataset(commonappdata + "\\",
                    DateTime.Now.ToString("yyMMddhmmss") + ".tiff", bitmapp);
                IRasterLayer pRastrLyr = new RasterLayerClass();
                pRastrLyr.CreateFromDataset(rasterds);
                var pSatelitelyr = (ILayer) pRastrLyr;
                pSatelitelyr.Name = "Raster Layer Name";
                ArcMap.Document.FocusMap.AddLayer(pSatelitelyr);

ExportMapImageUrl function

    public static byte[] ExportMapImageUrl(IImageServer imageServer, IRecordSet items, int thumbwidth)
    {
        ICursor pCursor = items.Table.Search(null, false);
        IRow pRow = pCursor.NextRow();
        IImageServer2 imageServer2 = (IImageServer2)imageServer;
        IMosaicRule mosaicRule = new MosaicRuleClass();
        mosaicRule.MosaicMethod = esriMosaicMethod.esriMosaicLockRaster;
        mosaicRule.LockRasterID = pRow.get_Value(0).ToString();
        mosaicRule.MosaicOperatorType = rstMosaicOperatorType.MT_MAX;

        IGeoImageDescription2 geoImageDesc = new GeoImageDescriptionClass();
        geoImageDesc.PixelType = rstPixelType.PT_UCHAR;
        var wdim = (_envpoint.XMax - _envpoint.XMin) / thumbwidth;

        geoImageDesc.Height = Convert.ToInt32((_envpoint.YMax - _envpoint.YMin)/wdim);
        geoImageDesc.Width = thumbwidth;
        geoImageDesc.Interpolation = rstResamplingTypes.RSP_BilinearInterpolation;
        geoImageDesc.NoData = 0;
        geoImageDesc.Extent = _envpoint;
        geoImageDesc.MosaicRule = mosaicRule;

        IImageType imgType = new ImageTypeClass();
        imgType.Format = esriImageFormat.esriImageJPGPNG;
        imgType.ReturnType = esriImageReturnType.esriImageReturnMimeData;
        IMapImage mapImage = imageServer2.ExportMapImage(geoImageDesc, imgType);

        return mapImage.MimeData;
    }

Create Raster Dataset in Memory

         public static IRasterDataset CreateRasterDataset(string Path, string FileName, Bitmap bts)
    {
        try
        {
            IRasterWorkspace2 rasterWs = OpenRasterWorkspace(Path);
            ISpatialReference sr = new UnknownCoordinateSystemClass();
            IPoint origin = new PointClass();
            origin.PutCoords(_envpoint.XMin, _envpoint.YMin);

            int width = bts.Width; 
            int height = bts.Height;
            double xCell = (_envpoint.XMax - _envpoint.XMin) / width;
            double yCell = (_envpoint.YMax - _envpoint.YMin) / height;
            int NumBand = 3; 
            //MEM is memory
            IRasterDataset rasterDataset = rasterWs.CreateRasterDataset(FileName, "MEM",
                origin, width, height, xCell, yCell, NumBand, rstPixelType.PT_UCHAR, sr,
                true);

            IRasterBandCollection rasterBands = (IRasterBandCollection)rasterDataset;
            IRasterBand rasterBand;
            IRasterProps rasterProps;
            rasterBand = rasterBands.Item(0);
            rasterProps = (IRasterProps)rasterBand;

            rasterProps.NoDataValue = 255;

            IRaster raster = rasterDataset.CreateDefaultRaster();

            IPnt blocksize = new PntClass();
            blocksize.SetCoords(width, height);
            IPixelBlock3 pixelblock = raster.CreatePixelBlock(blocksize) as IPixelBlock3;

            for (int k = 0; k < 3; k++)
            {
                var pixels = (Array)pixelblock.PixelData[k];
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        if (k == 0)
                        {
                            pixels.SetValue(Convert.ToByte(bts.GetPixel(i, j).R), i, j);
                        }

                        if (k == 1)
                        {
                            pixels.SetValue(Convert.ToByte(bts.GetPixel(i, j).G), i, j);
                        }

                        if (k == 2)
                        {
                            pixels.SetValue(Convert.ToByte(bts.GetPixel(i, j).B), i, j);
                        }
                    }
                }
                pixelblock.PixelData[k]= pixels;
            }
            IPnt upperLeft = new PntClass();
            upperLeft.SetCoords(0, 0);
            IRasterEdit rasterEdit = (IRasterEdit)raster;
            rasterEdit.Write(upperLeft, (IPixelBlock)pixelblock);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(rasterEdit);

            return rasterDataset;
        }
        catch (Exception ex)
        {
        }
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.