ThinkGeo.com    |     Documentation    |     Premium Support

Url filepath for gdiplusrasterlayer

 I am trying to build some image based layers using GDIPlusRasterLayer. I have been using this with locally hosted images for the last few versions  with no problems. We have transitioned much of our web content (and applications) to Azure and my images are now on my Azure storage account. 


When I try the code below, I get' file specified does not exist' on my map. The image path is correct and the file does exist. How can I use my cloud hosted images in my maps?


myImagePath = "nexrfazurestorage.blob.core.windows.net/public/a029a223-6a8d-420c-b633-c1947e4d158e.png"


Dim gdiPlusImageLayer As New GdiPlusRasterLayer(myImagePath, myMapExtent)


 



hello? anyone out there?

David, 
  
   To my knowledge the GdiPlusRasterLayer constructor takes a pathFileName and not a URI. My guess is that since the file was local before somewhere in the Microsoft stack it just accepted your URI for a file location.  As we currently do not support proper URIs this means we cannot load the image from a remote server using the method above.  There is a way however to accomplish this and it is through our StreamLoading event.  If you hook to this, on the layer, even then you should find it being raised when it tries to load the image.  You can, in the event, do a web request on the URI and then take that stream and pass it along in the event arguments.  We use the StreamLoading event to allow you to intervene in the loading of the image and get it from whatever source you wanted.  In addition we could also consider adding URI support but this may not go in quickly as to do it right we need to consider many API to update. 
  
 David

I added the following code, but it appears that the event just continually fires. It just keeps looping through my handler sub and the map is never fully loaded. I would like to get the workaround working, but I think this is an important feature/request.



       Dim gdiPlusImageLayer As New GdiPlusRasterLayer(mappedPath, MapID & ImageFileExtension)


        If bWebImage Then


            'My.Computer.Network.DownloadFile(mappedPath, MapID & ".jpeg")


 


            'add custom handler to get hosted images to load properly


            AddHandler gdiPlusImageLayer.StreamLoading, Sub(sender As Object, e As ThinkGeo.MapSuite.Core.StreamLoadingEventArgs)


                                                            Dim request As WebRequest = WebRequest.Create(mappedPath)


                                                            Dim response As WebResponse = request.GetResponse()


                                                            Dim datastream As Stream = response.GetResponseStream()


                                                            ' We use a temporary MemoryStream, otherwise in some case, reading directly the stream from GetResponseStream()


                                                            ' throws an exception.


                                                            Dim buffer As Byte() = New Byte(1024) {}


                                                            Dim ms As New MemoryStream()


                                                            Dim read As Integer = datastream.Read(buffer, 0, buffer.Length)


                                                            While read > 0


                                                                ms.Write(buffer, 0, read)


                                                                read = datastream.Read(buffer, 0, buffer.Length)


                                                            End While


 


                                                            ms.Position = 0


                                                            e.AlternateStream = ms


                                                            e.AlternateStreamName = MapID


                                                            e.FileAccess = FileAccess.Read


                                                            e.FileMode = FileMode.Open


                                                        End Sub


        End If




 As another workaround, I have tried using isolatedstorage. I also get a file type not supported exception (on the map itself) when I try to do this. The file is the same old png and the path I get from the isloatedstorage filestream does open the file normally when put into explorer. Why won't this one work now?



        If bWebImage Then


            Dim sFileName As String = MapID.Trim & ImageFileExtension


            Try


                Dim f As IsolatedStorageFile = IsolatedStorageFile.GetMachineStoreForDomain


 


                Dim fs As IsolatedStorageFileStream


 


                If Not f.FileExists(sFileName) Then


                    Dim request As WebRequest = WebRequest.Create(mappedPath)


                    Dim response As WebResponse = request.GetResponse()


                    Dim s As Stream = response.GetResponseStream()


 


                    Dim buffer As Byte() = New Byte(1024) {}


                    fs = f.CreateFile(sFileName)


                    Dim read As Integer = s.Read(buffer, 0, buffer.Length)


                    While read > 0


                        fs.Write(buffer, 0, read)


                        read = s.Read(buffer, 0, buffer.Length)


                    End While


 


                    fs.Close()


                Else


                    fs = f.OpenFile(sFileName, FileMode.Open)


                    fs.Close()


                End If


                mappedPath = fs.[GetType]().GetField("m_FullPath", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(fs).ToString()


 


                '                My.Computer.Network.DownloadFile(mappedPath, MapID & ImageFileExtension)


            Catch ex As Exception


                Throw New Exception(ex.Message)


            End Try


        End If


 


 


        Dim gdiPlusImageLayer As New GdiPlusRasterLayer(mappedPath)




 David


Below is a sample on how to use the stream loading.  What I forgot to mention is how it works and I can see how it would be confusing without come guidance.  The key is that this event gets fired for each of the associated files.  For example in a raster file we need the real raster file and the world file.  This will cause this event to fire two times.  Also this event fires after the layer is closed, re-opened and data is requested.  Because of this we suggest you cache the stream you are using.  Beware we may call the close of the stream in the Close of the layer so you may need a separate byte array version or something.  Below I have also cut out the relevant code form the sample.  You can see that we provide some useful stuff int he arguments of the event such as the file type we are expecting etc.


wiki.thinkgeo.com/wiki/Map_Suite_Services_Edition_Layers_%26_FeatureSources_Samples#Image_Stream_Loading




   void MainForm_StreamLoading(object sender, StreamLoadingEventArgs e)
        {
            if (e.StreamType == "Image File")
            {
                Stream stream = new FileStream(@"..\..\Data\world.tif", FileMode.Open, FileAccess.Read);
                e.AlternateStream = stream;
            }
 
            if (e.StreamType == "World File")
            {
                Stream stream = new FileStream(@"..\..\Data\world.tfw", FileMode.Open, FileAccess.Read);
                e.AlternateStream = stream;
            }
        }