This is a migrated thread and some comments may be shown as answers.

UriImageProvider Questions

8 Answers 159 Views
Map
This is a migrated thread and some comments may be shown as answers.
Seth
Top achievements
Rank 1
Seth asked on 11 Oct 2011, 12:16 AM
Howdy,

I have two questions dealing with the UriImageProvider:

1) Are there limits to what size/resolution image you should use with the UriImageProvider? I seem to be unable to load files that have huge resolution (25,200 x 18,000 3.3 MB GIF for example).

2) I need to be able to hide/disable the grey area of the map control when using UriImageProvider. I am allowing users to drag MapPinPoints onto the map, but want to deny them ability to do so outside the bounds of the underlying image. Any ideas how this can be accomplished? I also would like to prevent zooming too high so that the user can no longer see the image (I would hope that I could look at the underlying image, check the resolution, and set the MinZoomLevel of the map control based on it's size).

Thanks,
Seth

8 Answers, 1 is accepted

Sort by
0
Seth
Top achievements
Rank 1
answered on 12 Oct 2011, 10:18 PM
UPDATE:

On question 2, I have figured out that if I am working with an image that is 1650 x 1275 resolution and I set the following properties it works the way I need it to (no out of bounds is available to the user):
  • RadMap.ZoomLevel="13"
  • RadMap.MinZoomLevel="13"
  • RadMap.GeoBoundsNW="-.125,0"
  • RadMap.GeoBoundsSE="-.885,1"
  • UriImageProvider.GeoBoundsNW="0,0" 
  • UriImageProvider.GeoBoundsSE="-1,1"

So my new question 2 is, how do I determine at run-time what my properties above should be set to given the resolution of the image I am about to use for my provider? It appears it has something to do with the ratio of height to width of the underlying image, but that's just a guess based on trying various sized images.

Thanks,
Seth
0
Seth
Top achievements
Rank 1
answered on 13 Oct 2011, 01:01 AM
UPDATE:

Ok, I have figured out the formula for determining the correct GeoBounds for the RadMap when using images via the UriImageProvider:

Dim oImage = New BitmapImage(New Uri("pack://application:,,," + UriImageProvider1.Uri.OriginalString))
 
Dim wNwLatitude = (1 - (oImage.Height / oImage.Width)) / 2
Dim wSeLatitude = -1 * (1 - wNwLatitude)
wNwLatitude = wNwLatitude * -1
 
radMap.GeoBoundsNW = New Location(wNwLatitude, 0)
radMap.GeoBoundsSE = New Location(wSeLatitude, 1)

So now I need to figure out how to determine the ZoomLevel, MinZoomLevel, MaxZoomLevel, and the Center for an image, regardless of size, that I load. I have tried using the InformationLayer.GetBestView and I have tried creating my own GetBestView routine using posts from this forum. Both attempts don't set the Zoom levels correctly. I am thinking that they were not written with UriImageProvider in mind. Maybe they are trying to use a Tile Size that doesn't apply in my scenario. Any advice?

Thanks,
Seth
0
Andrey
Telerik team
answered on 13 Oct 2011, 09:03 AM
Hi Seth,

1) Specially we didn't set any limits to the image for UriImageProvider. We use the WPF Image class for its rendering. So, the limits of size/resolution image you use depends just on the WPF Image class limitations. Rendering of a big image could take a lot of time.
 
2) You can restrict the zoom level in RadMap using the RadMap.MinZoomLevel and RadMap.MaxZoomLevel properties. Also you can restrict panning region in map using the RadMap.GeoBounds or RadMap.GeoBoundsNW and RadMap.GeoBoundsSE properties.
For more information please take a look at the following topic of documentation:
http://www.telerik.com/help/wpf/radmap-howto-limit-panning-zooming-region.html

Best wishes,
Andrey Murzov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Seth
Top achievements
Rank 1
answered on 13 Oct 2011, 06:22 PM
Thanks for the information, that is very helpful.

However, your answer to question 2 is not what I was looking for. I was already aware that I needed to set MinZoomLevel and MaxZoomLevel. My specific question was how to calculate those values for any given image since different sized images will need different zoom level constraints. My 3rd posting on this thread goes into details on what I tried. Any advice?

Thanks,
Seth
0
Seth
Top achievements
Rank 1
answered on 13 Oct 2011, 08:56 PM
I think I have come up with a solution:

Private Sub MainWindow_SizeChanged(ByVal sender As Object, ByVal e As System.Windows.SizeChangedEventArgs) Handles Me.SizeChanged
        SetCenterAndZoomByRectangle()
End Sub
     
Private Sub SetCenterAndZoomByRectangle()
        Dim oImage = New BitmapImage(New Uri("pack://application:,,," + UriImageProvider1.Uri.OriginalString))
 
        Dim wNwLatitude = (1 - (oImage.Height / oImage.Width)) / 2
        Dim wSeLatitude = -1 * (1 - wNwLatitude)
        wNwLatitude = wNwLatitude * -1
 
        Dim leftTop As New Location(wNwLatitude, 0)
        Dim rightBottom As New Location(wSeLatitude, 1)
 
        Dim centerLocation As Location = New Location((leftTop.Latitude + rightBottom.Latitude) / 2, (leftTop.Longitude + rightBottom.Longitude) / 2)
 
        radMap.GeoBoundsNW = leftTop
        radMap.GeoBoundsSE = rightBottom
        radMap.Center = centerLocation
 
        Dim leftTopPoint As Point = radMap.SpatialReference.GeographicToLogical(leftTop)
        Dim rightBottomPoint As Point = radMap.SpatialReference.GeographicToLogical(rightBottom)
 
        Dim viewportWidth As Double = rightBottomPoint.X - leftTopPoint.X
        Dim viewportHeight As Double = rightBottomPoint.Y - leftTopPoint.Y
        Dim proportionalWidth As Double = viewportWidth / radMap.ActualWidth
        Dim proportionalHeight As Double = viewportHeight / radMap.ActualHeight
        Dim tileSize As Double = (oImage.Width / oImage.Height) * 119
 
        If (proportionalWidth > proportionalHeight) Then
            radMap.ZoomLevel = Convert.ToInt32(Math.Log(radMap.ActualWidth / tileSize / viewportWidth, 2D))
            radMap.MinZoomLevel = Convert.ToInt32(Math.Log(radMap.ActualWidth / tileSize / viewportWidth, 2D))
        Else
            radMap.ZoomLevel = Convert.ToInt32(Math.Log(radMap.ActualHeight / tileSize / viewportHeight, 2D))
            radMap.MinZoomLevel = Convert.ToInt32(Math.Log(radMap.ActualHeight / tileSize / viewportHeight, 2D))
        End If
    End Sub

My only concern is with the tileSize formula. In previous posts it was always hard coded to 256. My formula appears to be working, but wasn't sure if I was overlooking something. Not really sure why a constant of 119 causes everything to work.

Thanks,
Seth
0
Andrey
Telerik team
answered on 18 Oct 2011, 09:15 AM
Hello Seth,

You shouldn't do it this way. Your image occupy geographical region with known boundaries. So you can use functionality provided by LocationRect class to calculate the nearest zoom level and coordinates of the map center so that your entire image will be visible:

Private Sub SetCenterAndZoomByRectangle()
 
    Dim oImage = New BitmapImage(New Uri("pack://application:,,," + UriImageProvider1.Uri.OriginalString))
 
    Dim geoSize As Size = Me.RadMap.GetGeoSize(New Location(0, 0), New Size(oImage.PixelWidth, oImage.PixelHeight))
    Dim view As LocationRect = New LocationRect( _
     New Location(0, 0), _
     New Location(-geoSize.Height, geoSize.Width))
    view.MapControl = Me.RadMap
    Me.RadMap.GeoBounds = view
    Me.RadMap.MinZoomLevel = view.ZoomLevel
    Me.RadMap.SetView(view)
 
End Sub


Best wishes,
Andrey Murzov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Seth
Top achievements
Rank 1
answered on 18 Oct 2011, 05:27 PM
Hi Andrey,

First of all, thank you for your response. I appreciate your help on this.

I tried swapping in your code that you provided. Everything works, but there is more grey area displaying then the image. In fact, of the entire available screen, the image only takes up about 25%. I need it to fill the entire screen (or at least the entire area the underlying app uses). My code sample does this.

On a sample image with the resolution of 8270 x 5297, your method sets the MinZoomLevel and the ZoomLevel to 8, and mine sets them to 10. Anything smaller then 10 for the initial start-up of the app is going to show grey space around the image. This is the problem I have always had trying to use this method and is why I started looking for another option.

Are you saying my approach will fail in certain cases, or is it just not as efficient?

Thanks,
Seth
0
Andrey
Telerik team
answered on 21 Oct 2011, 01:02 PM
Hello Seth,

Your code creates gegraphically incorrect result. You are based on the image pixel size what is incorrect. You must specify vaid geographical region (LocationRect) for your image and then use it for calculation. The way how you calculate location rectangle in your code is incorrect, because it use pixel image size directly. But same image cover geographical regions with different size depends on its location on the map (because of the Mercator projection) and depends on the current zoom level.

If you will use your code as is all other geographical operations (including positioning of the items over the map and so on) could produce wrong results for your image.

Best wishes,
Andrey Murzov
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
Map
Asked by
Seth
Top achievements
Rank 1
Answers by
Seth
Top achievements
Rank 1
Andrey
Telerik team
Share this question
or