none
WinRT - how to add an image that scales based on bounding box? RRS feed

  • Question

  • I have an image I want want to put on my map and have it scale based on the zoom level. If this had the same API as the WPF version, I could add a MapPolygon and use an ImageBrush.

    How can this be accomplished with the Bing.Map on an Windows Store application?

    This is how I am adding the image (and a Polygon to show the bounding box):

    imageLayer.Children.Clear(); MapLayer.SetPosition(_vm.RadarImage, new Location(_vm.Overlay.LatN, _vm.Overlay.LonW)); imageLayer.Children.Add(_vm.RadarImage); shapeLayer.Shapes.Clear(); var rect = new MapPolygon(); rect.Locations.Add(new Location(_vm.Overlay.LatN, _vm.Overlay.LonW)); rect.Locations.Add(new Location(_vm.Overlay.LatS, _vm.Overlay.LonW)); rect.Locations.Add(new Location(_vm.Overlay.LatS, _vm.Overlay.LonE)); rect.Locations.Add(new Location(_vm.Overlay.LatN, _vm.Overlay.LonE)); rect.FillColor = Colors.Green; shapeLayer.Shapes.Add(rect); map.SetView(new LocationRect(new Location(_vm.Overlay.LatN + 0.0001, _vm.Overlay.LonW + 0.0001), new Location(_vm.Overlay.LatS - 0.0001, _vm.Overlay.LonE - 0.0001)));

    Here's the image scaled close to accurate.

    If you zoom out, the image stays the same size, but the Rect and Tiles scale.


    Tuesday, January 7, 2014 4:24 PM

Answers

  • There isn't a simple solution for this. I have put together a sample app that shows one approach to do this. You can find it here: http://code.msdn.microsoft.com/Binding-and-Image-to-a-01a56e48 What I did was add a Canvas to the map, and then use the map to calculate the pixel coordinates of the bounding box for the image. I then used these pixel coordinates to scale and position the image on the canvas overtop the map. I've done something similar to create custom polygons that support image brushes in the past but haven't uploaded that code sample yet.

    http://rbrundritt.wordpress.com

    • Proposed as answer by Ricky_Brundritt Wednesday, January 15, 2014 12:11 PM
    • Marked as answer by mhectorgato Thursday, January 16, 2014 2:54 AM
    Wednesday, January 15, 2014 12:11 PM
  • The WP8 map control doesn't have this functionality, however it is possible to calculate these values. First you will need the tile math code from here: http://msdn.microsoft.com/en-us/library/bb259689.aspx

    Once you have this you will then need to take the top left coordinate of the map. Since there is no Bounds property or some other nice property to get this information you will need to use the center of the map and convert it to a global pixel coordinate using the LatLongToPixelXY method. Once you have this you can offset the value to get the top left corner global pixel coordinate by subtracting the x by width/2 and the Y by height/2.

    Next use the LatLongToPixelXY  method on the top left and bottom right corners of your bounding box. This will give you global pixel coordinates. You will now want to convert them to local pixel coordinates by subtracting the top left map corner pixel coordinates from  the X and Y values you just calculated for your bounding box. This will result in the pixel coordinates you need to position your image on the canvas.


    http://rbrundritt.wordpress.com

    Thursday, January 16, 2014 11:12 AM

All replies

  • What am I doing wrong? There's been no responses here nor on my Stackoverflow  question(http://stackoverflow.com/questions/20942793/winrt-bing-maps-how-add-a-image-with-a-lat-lon-bounding-box)

    Is there any other information that I need to provide?


    • Edited by mhectorgato Tuesday, January 14, 2014 5:46 PM
    Tuesday, January 14, 2014 5:29 PM
  • There isn't a simple solution for this. I have put together a sample app that shows one approach to do this. You can find it here: http://code.msdn.microsoft.com/Binding-and-Image-to-a-01a56e48 What I did was add a Canvas to the map, and then use the map to calculate the pixel coordinates of the bounding box for the image. I then used these pixel coordinates to scale and position the image on the canvas overtop the map. I've done something similar to create custom polygons that support image brushes in the past but haven't uploaded that code sample yet.

    http://rbrundritt.wordpress.com

    • Proposed as answer by Ricky_Brundritt Wednesday, January 15, 2014 12:11 PM
    • Marked as answer by mhectorgato Thursday, January 16, 2014 2:54 AM
    Wednesday, January 15, 2014 12:11 PM
  • Thank you!! This worked like a charm. I would imagine others would find it helpful to have this in future Map controls.

    Most of this works in a WP8 app as well except for these lines. Any idea on how to port this to that environment?

    var bounds = _map.Bounds;

    _map.TryLocationToPixel(Bounds.Northwest,

    outtopLeftPixel);

    _map.TryLocationToPixel(Bounds.Southeast,

    outbottomRightPixel);

    Again thank you.

    Thursday, January 16, 2014 3:04 AM
  • The WP8 map control doesn't have this functionality, however it is possible to calculate these values. First you will need the tile math code from here: http://msdn.microsoft.com/en-us/library/bb259689.aspx

    Once you have this you will then need to take the top left coordinate of the map. Since there is no Bounds property or some other nice property to get this information you will need to use the center of the map and convert it to a global pixel coordinate using the LatLongToPixelXY method. Once you have this you can offset the value to get the top left corner global pixel coordinate by subtracting the x by width/2 and the Y by height/2.

    Next use the LatLongToPixelXY  method on the top left and bottom right corners of your bounding box. This will give you global pixel coordinates. You will now want to convert them to local pixel coordinates by subtracting the top left map corner pixel coordinates from  the X and Y values you just calculated for your bounding box. This will result in the pixel coordinates you need to position your image on the canvas.


    http://rbrundritt.wordpress.com

    Thursday, January 16, 2014 11:11 AM
  • The WP8 map control doesn't have this functionality, however it is possible to calculate these values. First you will need the tile math code from here: http://msdn.microsoft.com/en-us/library/bb259689.aspx

    Once you have this you will then need to take the top left coordinate of the map. Since there is no Bounds property or some other nice property to get this information you will need to use the center of the map and convert it to a global pixel coordinate using the LatLongToPixelXY method. Once you have this you can offset the value to get the top left corner global pixel coordinate by subtracting the x by width/2 and the Y by height/2.

    Next use the LatLongToPixelXY  method on the top left and bottom right corners of your bounding box. This will give you global pixel coordinates. You will now want to convert them to local pixel coordinates by subtracting the top left map corner pixel coordinates from  the X and Y values you just calculated for your bounding box. This will result in the pixel coordinates you need to position your image on the canvas.


    http://rbrundritt.wordpress.com

    Thursday, January 16, 2014 11:12 AM
  • Thanks for the reply -- I'll give it a try soon.

    From a dev standpoint, I hope Threshold, or whatever the next set of updates, will unify APIs as much as possible across platforms. 

    Just for this feature, which I would imagine (in my limited view) would be a typical mapping function, (which I am surprised is not handled by the map control itself) there is a platform specific solution:

    WPF - Polygon with Image brush

    Win8 - Use Bound method of map

    WP8 - Use screen pixel calcs

    JS - ??? not tried, but guessing it would be a different API.

    Not a criticism, but just remark about the difficulties presented by different implementations of what externally seems as if it should be a single unified "Bing Map" control.


    • Edited by mhectorgato Thursday, January 16, 2014 5:37 PM to fix my bad grammar
    Thursday, January 16, 2014 3:12 PM
  • I know your pain. I've complained about this a lot.

    http://rbrundritt.wordpress.com

    Thursday, January 16, 2014 11:48 PM
  • The WP8 map control doesn't have this functionality, however it is possible to calculate these values. First you will need the tile math code from here: http://msdn.microsoft.com/en-us/library/bb259689.aspx

    Once you have this you will then need to take the top left coordinate of the map. Since there is no Bounds property or some other nice property to get this information you will need to use the center of the map and convert it to a global pixel coordinate using the LatLongToPixelXY method. Once you have this you can offset the value to get the top left corner global pixel coordinate by subtracting the x by width/2 and the Y by height/2.

    Next use the LatLongToPixelXY  method on the top left and bottom right corners of your bounding box. This will give you global pixel coordinates. You will now want to convert them to local pixel coordinates by subtracting the top left map corner pixel coordinates from  the X and Y values you just calculated for your bounding box. This will result in the pixel coordinates you need to position your image on the canvas.


    http://rbrundritt.wordpress.com

    Finally got a chance to try this out on the phone. Not sure I'm doing it right. Is LevelOfDetail == ZoomLevel?

                    var level = map.ZoomLevel;
                    int outLat, outLon;
                    Microsoft.MapPoint.TileSystem.LatLongToPixelXY(
                        map.Center.Latitude, 
                        map.Center.Longitude, 
                        (int)level, 
                        out outLat, out outLon);

                    int tlLeft = outLat / 2;
                    int tlTop = outLon / 2;
                    int brRight = outLat * 2;
                    int brBottom = outLon * 2;

    My debug output:

    tlLeft 67 int
    tlTop 117 int
    brRight 270 int
    brBottom 468 int
    level 1.6759999990463257 double
    Tuesday, January 21, 2014 3:50 AM
  • Yes, LevelOfDetail == ZoomLevel

    http://rbrundritt.wordpress.com

    Tuesday, January 21, 2014 9:58 AM
  • I have been beating my head on this same thing, overlay a radar image on a Silverlight Windows Phone 8.1 app with VS2013. None of the classes (that most seem to use) seem to be available.  I can get the image to overlay (using TileSource), but them it puts a copy of the overlay on each tile of the map, and then I also have the same scaling issue.  Any help or pointers would be appreciated. 
    Thursday, April 9, 2015 8:39 PM