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

Calculate view port from a location rect.

6 Answers 334 Views
Map
This is a migrated thread and some comments may be shown as answers.
Clint Singer
Top achievements
Rank 1
Clint Singer asked on 20 Nov 2009, 06:26 PM
Hi,

I can't seem to find a mechanism to resolve a center point and zoom level if all I have is a geographic rectangle.  Basically I would like to pass in something like the LocationRect.  Perhaps you can add to the RadMap a method like .ZoomTo(new LocationRect(...)) where this internally resolves what the center point and zoom level should be.

Or perhaps there could be a property called ViewPort which is also a location rect.  Modifying it could do the same thing as what .ZoomTo() would have done.  But you could also read from it and it could contain the new view port rectangle if someone had changed the the ZoomLevel and Center properties.

Also it would be great if there was a LocationRect (or equivalent) that takes latitude and longitude for both the top left and bottom right coordinates.  I realize the world is round so arguably it isn't going to be a true rectangle but the mercator projection should resolve this issue.

Cheers,
Clint

6 Answers, 1 is accepted

Sort by
0
Clint Singer
Top achievements
Rank 1
answered on 23 Nov 2009, 08:55 PM
Hi,

Anyone have any ideas what I can do about solving this in the short term?  It seems that any information that I would need to be able to calculate an appropriate zoom level based on a LocationRect is hidden away so that it isn't publicly accessible.

Basically I want to do what the Selection zoom feature does but do without having the user drawing the rectangle.

Cheers,
Clint
0
Andrey
Telerik team
answered on 24 Nov 2009, 08:18 AM
Hi Clint,

Thank you for contacting us.

The two sample methods below calculate center and zoom according to map width, height and provider's tile size. The first method has the LocationRect as parameter. The second uses as parameters the top left and bottom right coordinates.

private void SetCenterAndZoomByRectangle(LocationRect rect)
{
    Size degreeSize = this.radMap.GetLatitudeLongitudeSize(rect.Northwest, rect.Width, rect.Height);
    Location centerLocation = new Location(rect.North - degreeSize.Height / 2,
        rect.West + degreeSize.Width / 2);
    this.radMap.Center = centerLocation;
    double tileSize = 256;
    double viewportWidth = degreeSize.Width / 360;
    double viewportHeight = degreeSize.Height / 180;
    if (viewportWidth / this.radMap.ActualWidth < viewportHeight / this.radMap.ActualHeight)
    {
        viewportWidth = viewportHeight;
    }
    int zoomLevel = (int)Math.Log(this.radMap.ActualWidth / tileSize / viewportWidth, 2d);
    this.radMap.ZoomLevel = zoomLevel;
}
private void SetCenterAndZoomByRectangle(Location leftTop, Location rightBottom)
{
    Location centerLocation = new Location((leftTop.Latitude + rightBottom.Latitude) / 2,
        (leftTop.Longitude + rightBottom.Longitude) / 2);
    this.radMap.Center = centerLocation;
    double tileSize = 256;
    double viewportWidth = (rightBottom.Longitude - leftTop.Longitude) / 360;
    double viewportHeight = (leftTop.Latitude - rightBottom.Latitude) / 180;
    if (viewportWidth / this.radMap.ActualWidth < viewportHeight / this.radMap.ActualHeight)
    {
        viewportWidth = viewportHeight;
    }
    int zoomLevel = (int)Math.Log(this.radMap.ActualWidth / tileSize / viewportWidth, 2d);
    this.radMap.ZoomLevel = zoomLevel;
}


Hope this helps.


Greetings,
Andrey Murzov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Clint Singer
Top achievements
Rank 1
answered on 24 Nov 2009, 07:01 PM
Hi,

I am having difficulty with the resulting zoom level.  In my scenario it seems to wahnt to give me 17 most of the time when 16 or a 15 would have been necessary to see all of the items within the rectangle.  I tried different map actual sizes by resizing the window and had similar results no matter what I used.

Any ideas?

Cheers,
Clint
0
Andrey
Telerik team
answered on 26 Nov 2009, 01:57 PM
Hello Clint,

I am sorry about this confusion. I have re-inspected the zoom calculation so now it uses the provider's spatial reference and it should work as expected.

private void SetCenterAndZoomByRectangle(LocationRect rect)
{
    Size degreeSize = this.radMap.GetLatitudeLongitudeSize(rect.Northwest, rect.Width, rect.Height);
    Location rightBottom = new Location(rect.North - degreeSize.Height,
        rect.West + degreeSize.Width);
    this.SetCenterAndZoomByRectangle(rect.Northwest, rightBottom);
}
private void SetCenterAndZoomByRectangle(Location leftTop, Location rightBottom)
{
    Location centerLocation = new Location((leftTop.Latitude + rightBottom.Latitude) / 2,
        (leftTop.Longitude + rightBottom.Longitude) / 2);
    this.radMap.Center = centerLocation;
    Point leftTopPoint = this.radMap.SpatialReference.GeographicToLogical(leftTop);
    Point rightBottomPoint = this.radMap.SpatialReference.GeographicToLogical(rightBottom);
    double viewportWidth = rightBottomPoint.X - leftTopPoint.X;
    double viewportHeight = rightBottomPoint.Y - leftTopPoint.Y;
    double proportionalWidth = viewportWidth / this.radMap.ActualWidth;
    double proportionalHeight = viewportHeight / this.radMap.ActualHeight;
    double tileSize = 256;
    if (proportionalWidth > proportionalHeight)
    {
        this.radMap.ZoomLevel = (int)Math.Log(this.radMap.ActualWidth / tileSize / viewportWidth, 2d);
    }
    else
    {
        this.radMap.ZoomLevel = (int)Math.Log(this.radMap.ActualHeight / tileSize / viewportHeight, 2d);
    }
}

Best regards,
Andrey Murzov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Clint Singer
Top achievements
Rank 1
answered on 27 Jan 2010, 01:27 AM
Hi,

I have been using the above code in a partially successful way.  One of my requirements is to zoom in on an area of the map depending on where the user needs to be when the application first loads.  I have been doing this by hooking into the maps SizeChanged event because the above code requires access to ActualWidth and ActualHeight which haven't been initialized (i.e. they are still 0.0) until the map has resized a couple of times.

Unfortunately this also means that when the window resizes the map resets its size to the default "bounds".  I would like to separate the logic from the SizeChanged event but I am not sure where I can set this value so that I can get a correctly calculated zoom rectangle.

Any ideas?

Cheers,
Clint 
0
Clint Singer
Top achievements
Rank 1
answered on 27 Jan 2010, 02:09 AM
Never mind...

I was being dumb and didn't think to try the Loaded event on the map control.    I am now and and it is doing the trick.

Cheers,
Clint
Tags
Map
Asked by
Clint Singer
Top achievements
Rank 1
Answers by
Clint Singer
Top achievements
Rank 1
Andrey
Telerik team
Share this question
or