ThinkGeo.com    |     Documentation    |     Premium Support

GoogleMaps layer vs GoogleMapsOverlay

Hello,


I have implemented Google Maps using an instance of GoogleMapsLayer Class that is added to my own overlay I have inherited from LayerOverlay Class.


I noticed that performance is very bad. Even when pan or zoom it takes long time (>10 sec) if map is shown. So I made some test  and noticed if I use GoogelMapsOverlay Class the map performance is much better.


What is difference between GoogleLayer/Overlay Class.


Is there an solution (not turning on cache) I can speed up the GoogleLayer Class?


Otherwise I have to use GoogleOverlay but then I have to change my code because I have my own overlay class inherited from LayerOverlay.


Thomas



Thomas, 



I compared the GoogleMapsOverlay and GoogleMapsLayer, actually the performance is very closest when I processed the pan, zoom in/out operations between these two classes. I'm not sure where is your problem? I just show you my test code both for the two classes below: 



1, For GoogleMapsLayer: 




  private void Sample_Load(object sender, EventArgs e)         
{
            GoogleMapsLayer layer = new GoogleMapsLayer(@"ABQIAAAAX_L0oJKT0IU2n0u0qxcr3BR3rCYD_eVzP3e6DX1YTr2ah9RbohStaDJYLxi99hL16CJfmL4rjnw9wA", "C:\\ImageCache");
            engine.StaticLayers.Add(layer);
            
            RefreshMap();
        }

 private void RefreshMap()
        {
            Bitmap image = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            GoogleMapZoomLevelSet set = new GoogleMapZoomLevelSet();
            double snappedScale = set.GetZoomLevel(currentExtent, image.Width, mapUnit).Scale;
            RectangleShape snappedExtent = ExtentHelper.ZoomToScale(snappedScale, currentExtent, mapUnit, image.Width, image.Height);
            engine.CurrentExtent = ExtentHelper.GetDrawingExtent(snappedExtent, image.Width, image.Height);
            engine.OpenAllLayers(); 
            engine.DrawStaticLayers(image, mapUnit);
            if (pictureBox1.Image != null) { pictureBox1.Image.Dispose(); }
            pictureBox1.Image = image;
        }

        private void panRight_Click(object sender, EventArgs e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            currentExtent.TranslateByOffset(currentExtent.Width * 0.3, 0, GeographyUnit.Meter, DistanceUnit.Meter);
            RefreshMap();
            watch.Stop();
            lblStopWatchTime.Text = string.Format("{0} ms", watch.Elapsed.TotalMilliseconds.ToString());
        }

        private void panLeft_Click(object sender, EventArgs e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            currentExtent.TranslateByOffset(-currentExtent.Width * 0.3, 0, GeographyUnit.Meter, DistanceUnit.Meter);
            RefreshMap();
            watch.Stop();
            lblStopWatchTime.Text = string.Format("{0} ms", watch.Elapsed.TotalMilliseconds.ToString());
        }

        private void panUp_Click(object sender, EventArgs e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            currentExtent.TranslateByOffset(0, currentExtent.Height * 0.3, GeographyUnit.Meter, DistanceUnit.Meter);
            RefreshMap();
            watch.Stop();
            lblStopWatchTime.Text = string.Format("{0} ms", watch.Elapsed.TotalMilliseconds.ToString());
        }

        private void panDown_Click(object sender, EventArgs e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            currentExtent.TranslateByOffset(0, -currentExtent.Height * 0.3, GeographyUnit.Meter, DistanceUnit.Meter);
            RefreshMap();
            watch.Stop();
            lblStopWatchTime.Text = string.Format("{0} ms", watch.Elapsed.TotalMilliseconds.ToString());
        }

        private void zoomIn_Click(object sender, EventArgs e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            scaleNumber--;
            if (scaleNumber < 0)
            {
                scaleNumber = 0;
            }
            currentExtent = ExtentHelper.ZoomToScale(baseNumber * Math.Pow(2, scaleNumber), currentExtent, GeographyUnit.Meter, pictureBox1.Width, pictureBox1.Height);
            RefreshMap();

            watch.Stop();
            lblStopWatchTime.Text = string.Format("{0} ms", watch.Elapsed.TotalMilliseconds.ToString());
        }

        private void zoomOut_Click(object sender, EventArgs e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            scaleNumber++;
            if (scaleNumber > 19)
            {
                scaleNumber = 19;
            }
            currentExtent = ExtentHelper.ZoomToScale(baseNumber * Math.Pow(2, scaleNumber), currentExtent, GeographyUnit.Meter, pictureBox1.Width, pictureBox1.Height);            
            RefreshMap();

            watch.Stop();
            lblStopWatchTime.Text = string.Format("{0} ms", watch.Elapsed.TotalMilliseconds.ToString());
        }




2, For GoogleMapsOverlay: 



 
private void Sample_Load(object sender, EventArgs e) 

GoogleMapsOverlay overlay = new GoogleMapsOverlay(@"ABQIAAAAX_L0oJKT0IU2n0u0qxcr3BR3rCYD_eVzP3e6DX1YTr2ah9RbohStaDJYLxi99hL16CJfmL4rjnw9wA");           overlay.CacheDirectory = "C:\\ImageCache";             
LayerOverlay layerOverlay = new LayerOverlay();            
ShapeFileFeatureLayer shapeLayer = new ShapeFileFeatureLayer(@"..\..\SampleData\cntry02.SHP");          
Proj4Projection projection = new Proj4Projection();             projection.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);            
projection.ExternalProjectionParametersString = Proj4Projection.GetEsriExtraParametersString(900913);            shapeLayer.FeatureSource.Projection = projection;             shapeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;       
shapeLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.Color = GeoColor.FromArgb(32, 0, 0, 0);            
shapeLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.FillSolidBrush.Color = GeoColor.FromArgb(16, 255, 0, 0);            
shapeLayer.Open();          
layerOverlay.Layers.Add(shapeLayer);           
winformsMap1.Overlays.Add(overlay);            
winformsMap1.Overlays.Add(layerOverlay);           
winformsMap1.MapUnit = GeographyUnit.Meter;             
winformsMap1.ZoomLevelSnapping = ZoomLevelSnappingMode.Default;             
winformsMap1.ZoomLevelSet = new GoogleMapZoomLevelSet();          
winformsMap1.ThreadingMode = MapThreadingMode.SingleThreaded;           
RefreshMap(); 
}         

private void RefreshMap()      

GoogleMapZoomLevelSet set = new GoogleMapZoomLevelSet(); 
double snappedScale = set.GetZoomLevel(currentExtent, winformsMap1.Width, mapUnit).Scale;          
RectangleShape snappedExtent = ExtentHelper.ZoomToScale(snappedScale, currentExtent, mapUnit, winformsMap1.Width, winformsMap1.Height); 
winformsMap1.CurrentExtent = ExtentHelper.GetDrawingExtent(snappedExtent, winformsMap1.Width, winformsMap1.Height); 
winformsMap1.Refresh(); 


private void panUp_Click(object sender, EventArgs e) 

Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 
winformsMap1.Pan(PanDirection.Up, 30); 
winformsMap1.Refresh(); 
stopWatch.Stop(); 
lblStopWatchTime.Text = string.Format("{0} ms", stopWatch.Elapsed.TotalMilliseconds.ToString()); 


private void panDown_Click(object sender, EventArgs e) 

Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 
winformsMap1.Pan(PanDirection.Down, 60); 
winformsMap1.Refresh(); 
stopWatch.Stop(); 
lblStopWatchTime.Text = string.Format("{0} ms", stopWatch.Elapsed.TotalMilliseconds.ToString()); 


private void panLeft_Click(object sender, EventArgs e) 

Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 
winformsMap1.Pan(PanDirection.Left, 30); 
winformsMap1.Refresh(); 
stopWatch.Stop(); 
lblStopWatchTime.Text = string.Format("{0} ms", stopWatch.Elapsed.TotalMilliseconds.ToString()); 


private void panRight_Click(object sender, EventArgs e) 

Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 
winformsMap1.Pan(PanDirection.Right, 30); 
winformsMap1.Refresh(); 
stopWatch.Stop(); 
lblStopWatchTime.Text = string.Format("{0} ms", stopWatch.Elapsed.TotalMilliseconds.ToString()); 


private void zoomIn_Click(object sender, EventArgs e) 

Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 
scaleNumber--; 
if (scaleNumber < 0) 

scaleNumber = 0; 

currentExtent = ExtentHelper.ZoomToScale(baseNumber * Math.Pow(2, scaleNumber), winformsMap1.CurrentExtent, GeographyUnit.Meter, winformsMap1.Width, winformsMap1.Height); 

RefreshMap(); 
stopWatch.Stop(); 
lblStopWatchTime.Text = string.Format("{0} ms", stopWatch.Elapsed.TotalMilliseconds.ToString()); 


private void zoomOut_Click(object sender, EventArgs e) 

Stopwatch stopWatch = new Stopwatch(); 
stopWatch.Start(); 
scaleNumber++; 
if (scaleNumber > 19) 

scaleNumber = 19; 

currentExtent = ExtentHelper.ZoomToScale(baseNumber * Math.Pow(2, scaleNumber), winformsMap1.CurrentExtent, GeographyUnit.Meter, winformsMap1.Width, winformsMap1.Height); 
RefreshMap(); 
stopWatch.Stop(); 
lblStopWatchTime.Text = string.Format("{0} ms", stopWatch.Elapsed.TotalMilliseconds.ToString()); 




You can see I set the StopWatch object to record cost time for each operation on the map, the cost time is very closest for each operation between the GoogleMapsOverlayer and GoogleMapsLayer. You can test the performance for these 2 google extension classes used the code above. If you still find any problems please let me know again, 



Thanks, 



Scott, 

 



Hello Scott, 
  
 thanks for sample code. I see the speed difference might be an illusion. How is your experience using GoogleMaps  in DesktopEdition? 
  
 Over the last weeks I tested GoogleMap and recognized that if I display google in an small window I can work with it. But if I switch my form to full screen, performance goes down and often there is thrown an timeout-exception. 
  
 I use map in multithreaded mode. May be that causes other problems on requesting data from Google-Server because you can change extent while map loads data. I also have the impression that requesting data from Google-Server slows down on increasing number of extent changes. 
  
 Thanks Thomas 
  


Thomas, 
  
 About your problems, I just reproduced your first problem, when I switch my test form to full screen, the performance goes down and sometimes there is thrown an timeout exception. The reason is that when you request the response stream from the Google server, if the screen is so large, it caused the request data is large. I have set the timeout time to a enough large value so that this problem will not be occurred again. I have set it both for the GoogleMapsOverlay and GoogleMapsLayer. 
  
 About your second problem, I used the GoogleMapsOverlayer to test and set the map in multithreaded mode, but I can’t reproduce your problem correctly. Can you give me a sample to recreate it exactly? 
  
 Thanks, 
  
 Scott,

Hello Scott, 
  
 sorry for delay but I had to answer other thread in this forum. You mentioned that you have set the timeout time to a larger value. I have not found any property where I can change this. 
  
 About my second problem. I just wanted to know what happening inside MapSuite if I change my extent e.g. zoom in. Then while map is drawing the data I zoom in again. If I catch the currentScaleChanged Event of MapControl and display the current scale I can see while map is just drawing I can zoom in or with mousewheel and notic the currentScaleChanged Event is raised. 
  
 What happens inside map-control when map is still drawing and I request for another scale? Do you cancel the drawing? Strart a new thread? … 
  
 Thomas

Thomas, 
  
 Let me jump in and answer your first question, I have checked the dll packages and I found the version after 3.1.406 contains TimeroutInSeconds property both GoogleLayer and GoogleOverlay. 
  
 So I think you might use the old version that you still can not find it, please download the right version at Helpdesk.thinkgeo.com
  
 About another questions, I think Scott will give your answers tommorrow. 
  
 Thanks 
  
 James

Ok James you are right. I’m still developing with 3.1.299. 
  
 How about infos (map drawing) from James?

Thomas, 
  
 Actually, when map is drawing we cannot cacel the current drawing, the sample what I provided is based on the MapSuiteCore, it is the single thread program, I suggest you to use the MapSuite Desktop edition and use the multithread mode to try again. The desktop edition has a property that names ThreadingMode.MultiThreadingMode, you can set the map control to the multi threading mode and try your operations again. 
  
 Thanks, 
  
 Scott,