none
Loading complex shapes

    Question

  • Is there any method of loading large complex polygons quickly? I know threads and serialization are out of the question.

    Looping through

    LocationCollection.Add(New Location(x,y)) 

    is very slow, and what I can tell this is because of the overhead processing of the Location Object constructor.

    It seems almost impossible to load large objects after startup without locking up the UI? Or am I missing something?

    Wednesday, November 13, 2013 1:55 PM

Answers

  • you are correct that the Location object can only be created on the UI thread. I also find this a bit of a pain as I constantly want to do this asynchronously. That said it is possible to visualize large polygons on the Bing Maps control and have great performance. The trick is to reduce the resolution as needed. Chances are the resolution of your data is way more than what is needed. At zoom level 15, which is usually the closest most users zoom into a single pixel is equal to approximately 5 meters. At zoom level 7 (approximately country level) a single pixel is about 1.2km wide.

    Depending on the type of data you are displaying and the zoom levels you feel it would likely be viewed at most often you may be able to reduce the resolution of your data to reduce the number of coordinates without effecting the look of the shape.

    Another tip is to only show the data you need. If the user is zoomed in really close to the map but your data covers a large area then only load the data that is in view. You can then load additional data as the user moves the map.

    If your data set is massive and simply can't be reduced enough then you will need to look at a more in depth solution. You should embed large data sets in the application itself. Hosting the data on a server is a good option but having the user download a large data set would also be slow. However, if the data is on a server you can turn the data into a tile layer so that it can be viewed on the map with good performance. I have done this countless times in the past. Here is a demo I put together that has 175,000 high resolution polygons being displayed on a JavaScript map: http://onsbingmapsdemo.cloudapp.net/

    Another Windows Store app that uses this approach is called FloodAlerts: http://apps.microsoft.com/windows/en-gb/app/floodalerts/34357a3c-0da4-4b63-84a7-2360b10fd185 This app gets 60GB worth of flood data updated every 15 minutes but is able to visualize in real time in a Bing Maps app using Windows Azure to turn the data into a tile layer.

    Rather than going in too much more depth I'll stop the thread here so that you can give a bit more information around the size of data you are working with and the approach you are trying to use to visualize the data.


    http://rbrundritt.wordpress.com

    Wednesday, November 13, 2013 3:30 PM
  • When I say embedded data I mean you are storing the data locally in the app. The format could be SQLite, flat file or something along these lines.

    It is possible to create a great user experience using tiles and be able to response to UI events. To do this you would need to add an event to the map and then use that to trigger a search against the data. The easiest way to do this is to have a web service that connects to a spatial database where your data is stored. This is what I did for the ONS demo in my previous response.

    I'm in the process of writing a book on creating location intelligent windows store apps. The chapter I just finished the initial draft of is all about working with spatial data. If you want, send me an email at ricky_brundritt at Hotmail dot com and I'll send you a copy.


    http://rbrundritt.wordpress.com

    Friday, November 15, 2013 9:32 AM
  • Ok. I found my issue and thought I'd better post it incase someone else was having the same problem.

    It seems the LocationCollection object provides the functionality I was looking for in the MapPolygon and MapPolyline classes. Previously I was using the 'Add' method of the 'MapPolygon.Locations' object to add locations likes so:

    Dim poly as New Bing.Maps.MapPolygon poly.Locations.Add(New Bing.Maps.Location(y, x))

    Adding the locations to a new LocationCollection and then applying it to the 'MapPolygon.Locations' property is INFINITELY faster. Like so:

    Dim col as New Bing.Maps.LocationCollection
    Dim poly as New Bing.Maps.MapPolygon
    
    col.Add(New Bing.Maps.Location(y, x))
    poly.Locations = col
    I did not provide the correct code sample in my original post, apologies Ricky.

    Tuesday, November 19, 2013 3:04 AM

All replies

  • you are correct that the Location object can only be created on the UI thread. I also find this a bit of a pain as I constantly want to do this asynchronously. That said it is possible to visualize large polygons on the Bing Maps control and have great performance. The trick is to reduce the resolution as needed. Chances are the resolution of your data is way more than what is needed. At zoom level 15, which is usually the closest most users zoom into a single pixel is equal to approximately 5 meters. At zoom level 7 (approximately country level) a single pixel is about 1.2km wide.

    Depending on the type of data you are displaying and the zoom levels you feel it would likely be viewed at most often you may be able to reduce the resolution of your data to reduce the number of coordinates without effecting the look of the shape.

    Another tip is to only show the data you need. If the user is zoomed in really close to the map but your data covers a large area then only load the data that is in view. You can then load additional data as the user moves the map.

    If your data set is massive and simply can't be reduced enough then you will need to look at a more in depth solution. You should embed large data sets in the application itself. Hosting the data on a server is a good option but having the user download a large data set would also be slow. However, if the data is on a server you can turn the data into a tile layer so that it can be viewed on the map with good performance. I have done this countless times in the past. Here is a demo I put together that has 175,000 high resolution polygons being displayed on a JavaScript map: http://onsbingmapsdemo.cloudapp.net/

    Another Windows Store app that uses this approach is called FloodAlerts: http://apps.microsoft.com/windows/en-gb/app/floodalerts/34357a3c-0da4-4b63-84a7-2360b10fd185 This app gets 60GB worth of flood data updated every 15 minutes but is able to visualize in real time in a Bing Maps app using Windows Azure to turn the data into a tile layer.

    Rather than going in too much more depth I'll stop the thread here so that you can give a bit more information around the size of data you are working with and the approach you are trying to use to visualize the data.


    http://rbrundritt.wordpress.com

    Wednesday, November 13, 2013 3:30 PM
  • Thanks for the quick reply Ricky.

    I am currently loading local data using serialization, my intention is to use a custom web service down the track to allow greater flexibility. I will be looking into my data resolution as per your suggestion but I have already reduced this by more than 50% and want to make sure I don't loose too much detail as users will be zoomed in close quite often.

    Tiles don't really suit as I need to be able to respond to the objects UI events. When you talk about embedding data, do you mean as XAML objects?

    p.s. sifting through your blog is teaching me a lot. Much appreciated!

     
    Friday, November 15, 2013 7:15 AM
  • When I say embedded data I mean you are storing the data locally in the app. The format could be SQLite, flat file or something along these lines.

    It is possible to create a great user experience using tiles and be able to response to UI events. To do this you would need to add an event to the map and then use that to trigger a search against the data. The easiest way to do this is to have a web service that connects to a spatial database where your data is stored. This is what I did for the ONS demo in my previous response.

    I'm in the process of writing a book on creating location intelligent windows store apps. The chapter I just finished the initial draft of is all about working with spatial data. If you want, send me an email at ricky_brundritt at Hotmail dot com and I'll send you a copy.


    http://rbrundritt.wordpress.com

    Friday, November 15, 2013 9:32 AM
  • I am currently storing my data locally, my concerns are not the performance of retrieving the data but more the conversion to map objects used by the maps API. I think I will need to do a lot more research and testing before committing to a data model, I will definitely spend a bit more time on map layers as it would seem the resource intensive UI elements (mappolygon and mappolyline) may not be suited to these large datasets.

    I think these elements could benefit from a bulk add method using an array as input to optimize performance. It feels a little primitive having to loop through the creation of locations in this way. Especially when we must use the UI thread to do so. It makes these objects useful for a limit amount of applications.

    Would love to read the chapter, have sent through my email. Cheers

    Friday, November 15, 2013 10:15 AM
  • Ok. I found my issue and thought I'd better post it incase someone else was having the same problem.

    It seems the LocationCollection object provides the functionality I was looking for in the MapPolygon and MapPolyline classes. Previously I was using the 'Add' method of the 'MapPolygon.Locations' object to add locations likes so:

    Dim poly as New Bing.Maps.MapPolygon poly.Locations.Add(New Bing.Maps.Location(y, x))

    Adding the locations to a new LocationCollection and then applying it to the 'MapPolygon.Locations' property is INFINITELY faster. Like so:

    Dim col as New Bing.Maps.LocationCollection
    Dim poly as New Bing.Maps.MapPolygon
    
    col.Add(New Bing.Maps.Location(y, x))
    poly.Locations = col
    I did not provide the correct code sample in my original post, apologies Ricky.

    Tuesday, November 19, 2013 3:04 AM