ThinkGeo.com    |     Documentation    |     Premium Support

Very Large Number of Markers (Clickable)

Hi,



Firstly I would like to appreciate the tech team for the comprehensive Samples.It was pretty easy  to use the Maps using the samples.However, for one of my needs I am totally lost and not able to find a solution.I am trying to load a huge number of markers on my map (about one million, at this point … which will grow incrementally over the course of time).



I tried using FeatureSourceMarkerOverlay , ShapeFileFeatureLayer +  InMemoryMarkerOverlay and other methods but could not achieve what I wanted.the app either errors out or does not display anything.I have searched the forum but still couldn’t get the solution;may be I could not understand a few.



I would appreciate if someone could provide a sample on how these large number of markers can be overlay seamlessly with a decent performance and speed.These location of markers is based on list of coordinates from a  custom database .



Thanks…Kreez !!!

Hi Kreez, 



Welcome to Map Suite Forums! Following is our suggestions and some questions we are not clear, please check it out:


1.       As one million markers at one view would generate a huge element tree in Wpf and this absolutely will bring a bad  performance or potential issues. I guess maybe you can try clustering strategy, just like what we have supported in ClusterPointStyle:  it is a custom style  which we can use it to just show the ‘parent‘ markers at a high zoomlevel, and when we zoom into those “parent” markers, then we can see more sub-markers which includes in those parent markers. Here is a sample for clusterpointstyle: wiki.thinkgeo.com/wiki/Map_S…PointStyle


2.       Would you please let us know more details about your scenarios on the one million markers? Will the markers refresh dynamically as the time goes on?


 


Waiting for your further information,


Best regards,






Summer

Hello Summer , Thanks for the warm welcome. 
  
 1.The scenario is to display the user base of an organization/product spread across different cities,the user-hierarchy has 3-4 levels of users and the bottom level users sum up to a million as of now which is expected to grow 2-3 times at least by this year.The coordinates of these users based on their address are also available which I expect to show on the map.The groups can also be tagged to some location.The idea of clusterpointstyle looks good , but the question is how are these points mapped on the layout.how do I pass them to the API to be displayed at different zoom levels.How can the cities/states be highlighted at the same time.Your help will be greatly appreciated. 
  
 Thanks…Kreez

Hi Kreez,



Thanks for your further information, attached is the sample code for your consideration, and here is a test vedio on our end for your information: screencast.com/t/XdMlbm90anw

About How can the cities/states be highlighted at the same time? If the cities/states are from shape files. then a sample in HowDoIsample =>Dynamic Shape=>HighlightAFeatureOnTheMap should be helpful.

if you have any more question , please feel free to let us know.


Best Regards


Summer



Post11489.txt (2.58 KB)

Thanks a lot for the sample Summer.I appreciate the quick response. 
 There are two questions I have on the sample (I was able to run it perfectly) 
  
 1. When I change the Shape file to some other Shape file with correct extent details it does not display anything.I used the USStates.shp separately and along with the Countries02.shp  
 2.Where do I set the co-ordinates for these points in the program.Assume I have all coordinates(lat,long) of the one million points how do I use them. 
  
  
  
 Thanks again . . . Kreez !!!

Hi Kreez,



Thanks for your query,



About the first problem, with attached code in “firstProblem.txt”, it should be displayed now.



About the second problem, attahced code in “secondProblem.txt” should be one choice:



Please not that once “shpLayer.FeatureSource.CommitTransaction();”, then the data in the .shp file is also changed.



if you have any more question , please feel free to let us know.



Best Regards



Summer

firstProblem.txt (1.11 KB)
secondProblem.txt (948 Bytes)

Thanks for the samples Summer.Your examples work fine.But whenever I modify it to do what I need,I don’t see anything on the Map. May be I am being repetitive but let me explain what I need to do. I have some 1 million users divided into different groups spread across different cities in a country.I want to show these users on the map based on their street addresses. 
  
 As you suggested may be clusterpointstyle is the way to go where you can also chose to have your own* images.Am I correct in saying that to put a marker at a specific location on the map using LAT-LONG we need to add a Feature to the Layers? 
  
 So how do I add these LAT-LONG information to the MAP and how do I ensure that these will be rendered as clusters for initial levels.  
  
 Whenever I add a new feature to any layers it doesn’t render anything.As I have mentioned in my first post FeatureSourceMarkerOverlay , ShapeFileFeatureLayer +  InMemoryMarkerOverlay did not help too. 
  
 Thanks…Kreez !!! 


Hi Kreez, 



The firstProblem.txt code shows USStates.shp and Countries02.shp in map. 



The secondProblem.txt code shows how to add a point in map where you clicked. 



If you want to plot a marker at a specified location on map using LatLon, you need add a feature in ShapeFileFeatureLayer + InMemoryMarkerOverlay. So you’re right about this point. 



If you have a LatLon data, just create a point shape based it, then create feature based the point shape and add this feature to your layer. 



double lon = 80;


double lat = 80;


PointShape point = new PointShape(80, 80);


layer.FeatureSource.AddFeature(point);



And the ClusterPointStyle should be assigned to the layer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle. 



Please view the code in this sample for more detail code:



wiki.thinkgeo.com/wiki/Map_Suite_Desktop_Edition_Styles_Samples#ClusterPointStyle 



Regards, 



Don

Hi Kreez, 
  
 Thanks for your further information, there are some Supplement I’d like to add for ethans reply. 
  
 1.ShapeFileFeatureLayer + InMemoryMarkerOverlay, say FeatureSourceMarkerOverlay is not applicable for current situation, because clusterpointstyle is not applicable for FeatureSourceMarkerOverlay. And without using clusterpointstyle, 2-3 millions marker will make the performance very slow. 
  
 2.If you want to add your lat-long information to map, there are two ways to add them, first one is to add them to inmLayer with  
 inmLayer.InternalFeatures.Add(yourlat,yourlong), but millions of data will bring some performance issue not just in the map.refresh() but also in the adding inmLayer.InternalFeatures.Add(yourlat,yourlong). 
  
 So, we suggest you to use add these lat-long information into a shapefile then use ShapeFileFeatureLayer to display them with clusterpointstyle. About creating shapefile, here is a helpful link for you to create shapefile. thinkgeo.com/forums/MapSuite/tabid/143/aft/5399/Default.aspx. then the code in “Post11489.txt” could be applicable. 
  
 And if you want to add or update feature into one shapefile then you could use  
  
 shpLayer.FeatureSource.BeginTransaction(); 
 shpLayer.FeatureSource.UpdateFeature(featureyouwanttoupdate);//shpLayer.FeatureSource.AddFeature(new feature(yourlat,yourlong)); 
 shpLayer.FeatureSource.CommitTransaction(); 
  
 About “ensure that these will be rendered as clusters for initial levels”, if you want the data in shapefilefeaturelayer to use culsterpointstyle from zoomlevel01 to zoomlevel04 then you could use following code 
  
 ShapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(clusterPointStyle1); 
 ShapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level04; 
  
 if you have any more question , please feel free to let us know. 
  
 Best Regards 
  
 Summer


 Hi Don , Thanks for the pointers. Below is the code that I had written earlier and was stuck on how to optimize this code so that I can show a million points on the map that would be rendered in clusters in the initial zoom levels and then show the actual points with zoom 
 private void Map1_Loaded(object sender, RoutedEventArgs e)
        {
            
            Map1.MapUnit = GeographyUnit.DecimalDegree;
            Map1.CurrentExtent = new RectangleShape(-128, 51, -65, 19);
            Map1.Background = new SolidColorBrush(Colors.Honeydew);//Color.FromRgb(148, 196, 243));
            

            //Country
            ShapeFileFeatureLayer countriesLayer = new ShapeFileFeatureLayer(@"…\data\Countries02.shp");
            countriesLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.LightSteelBlue, GeoColor.StandardColors.MidnightBlue);
            countriesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            LayerOverlay loy = new LayerOverlay();
            loy.Layers.Add(countriesLayer);
            

            //States
            ShapeFileFeatureLayer shapeFileFeatureLayer = new ShapeFileFeatureLayer(@"…\data2\USStates.shp");
            shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 1), new GeoSolidBrush(GeoColor.StandardColors.SteelBlue)));
            shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.Turquoise, 8, GeoColor.StandardColors.Black));

            shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            //Adds the ShapeFileFeatureLayer to an LayerOverlay.

            loy.Layers.Add(shapeFileFeatureLayer);
            Map1.Overlays.Add(loy);


            InMemoryMarkerOverlay markerOverlay = new InMemoryMarkerOverlay();
           
            //Create 5 random points and add to the marker overlay
            PointShape p1 = new PointShape(-95.2806, 38.9554);
            PointShape p2 = new PointShape(-96.2806, 39.9554);
            PointShape p3 = new PointShape(-97.2806, 40.9554);
            PointShape p4 = new PointShape(-98.2806, 41.9554);
            PointShape p5 = new PointShape(-99.2806, 42.9554);

            Feature f1 = new Feature(p1);
            Feature f2 = new Feature(p2);
            Feature f3 = new Feature(p3);
            Feature f4 = new Feature(p4);
            Feature f5 = new Feature(p5);
          
      

            Uri uru = new Uri(@"…\Images\uparrow.png", UriKind.RelativeOrAbsolute);
            markerOverlay.ZoomLevelSet.ZoomLevel05.DefaultPointMarkerStyle.ImageSource = new BitmapImage(uru);
            markerOverlay.ZoomLevelSet.ZoomLevel05.DefaultPointMarkerStyle.Width = 16;
            markerOverlay.ZoomLevelSet.ZoomLevel05.DefaultPointMarkerStyle.Height = 16;
            markerOverlay.ZoomLevelSet.ZoomLevel05.DefaultPointMarkerStyle.ToolTip = "You are Here";
            markerOverlay.ZoomLevelSet.ZoomLevel05.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            markerOverlay.FeatureSource.BeginTransaction();
           
            markerOverlay.FeatureSource.AddFeature(f1);
            markerOverlay.FeatureSource.AddFeature(f2);
            markerOverlay.FeatureSource.AddFeature(f3);
            markerOverlay.FeatureSource.AddFeature(f4);
            markerOverlay.FeatureSource.AddFeature(f5);

            markerOverlay.FeatureSource.CommitTransaction();

            Map1.Overlays.Add(markerOverlay);


            Map1.Refresh();

          
        } 
 
  
 can you help me modify this code to achieve what I am trying to do 
  
 Thanks . . . Kreez !!! 


Hi Summer Sorry, I did not see that you had replied.Thanks for the details.I shall try to do that.But as I mentioned in one of my earlier posts the data may change incrementally so if I add the features to a shape file and modify it I will not be able to use it for a different filter. The data that is displayed on a day will* change in a week or a month or even the next day.



Also there are multiple filters on the UI screen that run on the million users.Which will return the subset of users.



For Ex: One view could be rendering all the million users as points on the map, the second view could be based on a filter where different types of users who are the subset of these same million users must be displayed… 



Thanks…Kreez !!!

Hi Kreez, 
  
 Thanks for your further information, about your post in "09-05-2013 10:47 AM" this is because you used markerOverlay.ZoomLevelSet.ZoomLevel05, so the markers will apear in zoomlevel5, following guiding vedio could show when the markers will display: screencast.com/t/NkKocnofin4 
  
 About the your post in "09-05-2013 10:54 AM", could I make a confirmation with you? Are the datas are stored in database and in different tables(each table has a  user-hierarchy)? if yes, then you could use one MsSql2008FeatureLayer for one table with cluster pointstyle to replace using ShapeFileFeatureLayer, and this way the filtering could be acheived. And once the data in the database is changed then the data in the map will be changed too. 
  
 Waiting for your futher information. 
  
 Summer

Hi Summer, 

Thanks for the Screencast and the details. I put the ZoomLevel as 05 on purpose so that I could give the levels 01-04 a different style (cluster style) which didn’t work.And I understand that you can’t set a cluster style to InMemoryMarkerOverlay.   



Regarding the data, YES the location is stored in the database something like  



 

UserId | GroupId | UserName | Corodinates 

      1   |   1     |   abcd   |   90.090,12.908 

 



Could you please share more details on how I can use the SQLServer feature for my need. Will it allow me to view/highlight different STATES / CITIES provided I have the shape files.i.e I may also want to add a filter based on the City. 



Thanks . . . Kreez !!!

Hi Kreez, 
  
 Thanks for your futher information, 
  
 If the field UserId is playing a role of column id and the field Corodinates is a geometry type then, following code could be used: 
 MsSql2008FeatureLayer sql2008Layer = new MsSql2008FeatureLayer(connectString, yourUserTable, "UserId"); 
  
 If "I have the shape files" means that "I have the shape files for the states and cities", then to filter the users by states could use following code: 
  
 Collection<Feature> stateToFilter= statesShpFileFeatureLayer.FeatureSource.GetFeaturesByColumnValue(cityNameColumn, "yourcityname")[0]; 
 Collection<Feature> usersInState = sql2008Layer.FeatureSource.GetFeaturesInsideBoundingBox(stateToFilter[0].GetBoundingBox(), ReturningColumnsType.AllColumns); 
  
 if you have any more question , please feel free to let us know. 
  
 Best Regards 
  
 Summer