ThinkGeo.com    |     Documentation    |     Premium Support

How to Improve Map Speed

Hello,


How to improve map speed about pan/ZoomIn/Out the map?


When I located on the map (by input long/lat) and get infromation of location.


Then, I pan/ZoomOut the map. It doesn't move quickly.


If I pan the map , it results as follows:


(When I add 3x layers)


(pan time)


WinformMaps draw time:00:00:02.3906250

WinformMaps draw time:00:00:02.3593750

WinformMaps draw time:00:00:02.3906250

WinformMaps draw time:00:00:02.4375000

WinformMaps draw time:00:00:02.3906250


(ZoomOut time)


WinformMaps draw time:00:00:01.6093750

WinformMaps draw time:00:00:01.2812500

WinformMaps draw time:00:00:01.0625000

WinformMaps draw time:00:00:01.0156250

WinformMaps draw time:00:00:00.9843750

WinformMaps draw time:00:00:01.1406250

WinformMaps draw time:00:00:01.2187500


But if I just add two layers (county and town), it still move slow.


(pan time)


WinformMaps draw time:00:00:02.1093750

WinformMaps draw time:00:00:02.0468750

WinformMaps draw time:00:00:02.0468750

WinformMaps draw time:00:00:02.0312500

WinformMaps draw time:00:00:02.0468750

WinformMaps draw time:00:00:02.0312500


(ZoomOut time)


WinformMaps draw time:00:00:02.1093750

WinformMaps draw time:00:00:01.7968750

WinformMaps draw time:00:00:01.1875000

WinformMaps draw time:00:00:00.9531250

WinformMaps draw time:00:00:00.7968750

WinformMaps draw time:00:00:00.6718750


I use follows code to calculate draw map time, I'm not sure it is correct.


 Private Sub winformsMap1_OverlaysDrawn(ByVal sender As Object, ByVal e As OverlaysDrawnWinformsMapEventArgs)

        ToolStripStatusLabel2.Text = (DateTime.Now - startTimeToDraw).ToString()

 End Sub

Private Sub winformsMap1_OverlaysDrawing(ByVal sender As Object, ByVal e As OverlaysDrawingWinformsMapEventArgs)

        startTimeToDraw = DateTime.Now

 End Sub


 


 



Carol,


You can use TileCache to improve your performance. The code is like:



            FileBitmapTileCache bitmapTileCache = new FileBitmapTileCache();
            bitmapTileCache.CacheDirectory = @"c:\cacheFoleder\";
            bitmapTileCache.CacheId = "World02CachedTiles";
            bitmapTileCache.ImageFormat = TileImageFormat.Png;

            staticOverlay.TileCache = bitmapTileCache;

Thanks


James


 



Thanks for your reply, James 
  
 it results as follows: 
 WinformMaps draw time:00:00:02.7031250 
 WinformMaps draw time:00:00:03.2656250 
 WinformMaps draw time:00:00:02.5781250 
 WinformMaps draw time:00:00:02.5937500 
 WinformMaps draw time:00:00:02.5000000 
 WinformMaps draw time:00:00:00.3906250 
 WinformMaps draw time:00:00:00.3906250 
 WinformMaps draw time:00:00:04.5468750 
 WinformMaps draw time:00:00:16.8437500 
 WinformMaps draw time:00:00:00.0468750 
 WinformMaps draw time:00:00:00.0468750 
  
 If I move the map to new location, it load slower than before. 
 But if I move the map to old location, it load fast. 
  
 And, if I open the map and move long time, it genernate many picture in my folder. 
  
 Have any idea to solve it? 
  


Carol, 
  
 I think that result is make sense. When move to new location, the map will draw and generate picture store in your folder, so the time will longer than no cache. 
 If move to old location, it will use the picture which already exist, so the time will shorter than no cache. 
  
 I don’ think there any thing should be solve, if you don’t want to save cache to disk, you can use InMemoryBitmapTileCache. 
  
 Thanks 
 James  


Carol, 
  
   While James is pointing you to a good idea using the cache I would like to look at why the overlays are drawing slowly.  One every overlay there should be a DrawingTime that is property and after you do a pan or zoom in you can check that property.  Also the Layer object had a DrawingTime as well, so if you are adding layers to a LayersOverlay you can get the main time from the Overlay but you can also get the layer times by themselves. 
  
   It seems like the times are high but i am not familiar with your data.  Can you tell me a little but about where the layers are coming from.  Are they shape files, from a database etc?  Are the layers complex at all?  If you could send us a screen-shot of what is being rendering and how quickly that would help out at well so we can see the relative density. 
  
 It also looks like a total of six overlays are drawing.  I see you have three and we have three which would be the ExtentInteractiveOverlays, The EditInteractiveOverlay and the TrackInteractiveOverlay however these drawing times should be much faster if you are not using them.  
  
 A Few Questions: 
  
 1. Are you doing shape editing and drawing track shapes?   
  
 2. Are you using the Winforms or the Wpf desktop edition?   
  
 3. Can you give me an idea of the speed of your computer as well so I can get an idea of what it should run like?   
  
 4. Can I get the version of the Desktop Edition you are on, you can get this byu calling the GetVersion on the Winforms Map control. 
  
 5. What are the source of your layers, I mean shapefiles etc and what are their sizes of the .shp 
  
 6. Just to check but if you used shapefiles did you build spatial indexes for them using the ShapefileFeatureLayer.BuildIndex? 
  
 7. Do you have each layer in a seperate overlay?  You can place many layers in one LayerOverlay and it will be a bit faster as it cuts out some of the overhead of multi overlays 
  
 8. What is your threading mode set too?  It is the ThreadingMode property on the Map control. 
  
 9.  Did you set the Overlay.IsBase = true on any of these overlays?  This will slow down the times a bit, just checking. 
  
 10. Did you set a background up at all, like a solid blue background? 
  
 11. Could you send a picture of what is being rendered so we can see the complexity?  If the info is sensaive can you e-mail it to support@thinkgeo.com and have it forwarded to David? 
  
 12. Can you email the loading code for the layers so we can check them out. 
  
 13. Are you projecting any of the data? 
  
   It does seem that something is going on but we will get to the bottom of it. 
  
 David

James, David, Thanks for your help. 
  
 James, I’d like to know have any other idea to improve it faster. :) (even if I generate picture store in my folder) If it just pay 0.x second I think it doesn’t run too slow. 
  
 If I want to use InMemoryBitmapTileCache. Just write follows code? (Sorry, I don’t know how to use TileCatch and when I should to use it) 
  
 Dim bitmapTileCache As InMemoryBitmapTileCache = New InMemoryBitmapTileCache() 
 worldOverlay.TileCache = bitmapTileCache 
  
 What is difference between FileBitmapTileCache() and InMemoryBitmapTileCache()? it is different in store image or not? 
  
 David, I have sent a mail to support@thinkgeo.com


Carol, 
  
 Yesterday I was busy working on new DesktopEdition release, but I didn’t want to delay your question, so I reply your question hastily, I should ask more questions which can help solve your problem, I have a question about the email which sent to support@thinkgeo.com, if you answer all questions from David, I will ask Support let them forward to me, if you didn’t answer them please answer David’s questions at the following post, it’s very important to help us solve your problem! 
  
 About InMemoryBitmapTileCache, your code is right, you can see our API is so easy for users. 
 The difference between FileBitmapTileCache and InMemoryBitmapTileCache is that: 
 FileBitmapTileCache is that cache image on the disk by file, however InMemoryBitmapTileCache cache image in memory as a memory block. 
 FileBitmapTileCache can use to pre-generate a set of or two and more tiles into hard disk for overlay as many zoom levels as time permits and dynamic switch which is current use by CacheId. InMemoryBitmapTilCache uses tiles for a short time and don’t want to save them into hard disk. 
  
 Remember, TileCache is just an option which can improve your performance. But from your description, I am sure there must be some reasons which lead the performance so bad, I will find them and solve the problem. 
  
 Please let me know if you have more questions. 
  
 Thanks. 
 James 


 


Carol,
You answers(blue color) are very helpful and I think I almost find the reason. And I also add my comments(Red color) 

According to your computer speed and the size of your data, also you are using text style and image as point style. The 1-2 seconds can accept, it’s normal.

One thing can increase your speed is that you need give us your loading code and than we can analysis it.


1. Are you doing shape editing and drawing track shapes? 

No (I don't know you means in this program? because I have edit shp file by other program (to divide shp file)) 

So you mean you doing shape editing in another problem but not in this program



2. Are you using the Winforms or the Wpf desktop edition? 

Winforms Cool, for some reason Wpf will slower than winforms



3. Can you give me an idea of the speed of your computer as well so I can get an idea of what it should run like? 

CPU 1.4GHz, 800 MHz FSB 

Your CPU speed is slower than I image



4. Can I get the version of the Desktop Edition you are on, you can get this byu calling the GetVersion on the Winforms Map control. 

MapSuiteCore:3.1.273;DesktopEdition:3.0.453 The version almost the latest one



5. What are the source of your layers, I mean shapefiles etc and what are their sizes of the .shp 

.shp, .dbf, .ids, .idx, .shx  and all of .shp files size is 150 MB (all of all files is 8xx MB) 

The size of shape files is bigger than I image



6. Just to check but if you used shapefiles did you build spatial indexes for them using the ShapefileFeatureLayer.BuildIndex? 

Yes  Cool, buildindex will generate index files which can increase speed



7. Do you have each layer in a seperate overlay? You can place many layers in one LayerOverlay and it will be a bit faster as it cuts out some of the overhead of multi overlays 

No, I place layers(county, town, road...etc) to one overlay.  One overlay will be faster than multi overlays

but I place some overlays in SpatialQuery() , RoadQuery(), NodeQuery() and focus_b_Click() These things can not interfere the time of drawing



8. What is your threading mode set too? It is the ThreadingMode property on the Map control. 

Sorry, I don't what you mean...So I think you use default threading mode
9. Did you set the Overlay.IsBase = true on any of these overlays? This will slow down the times a bit, just checking. 

I never use this command, so, I have to command Overlya.IsBase=fase?So you didn’t set that, so I think you use the default value false
10. Did you set a background up at all, like a solid blue background? 

 WinformsMap1.BackgroundOverlay.BackgroundBrush = New GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean) 

  Cool, solid brush is faster than other advanced brush
11.Could you send a picture of what is being rendered so we can see the complexity? If the info is sensaive can you e-mail it to support@thinkgeo.com and have it forwarded to David? Sent 

From your screen-shot, I find that you add label by text style, right? It will cost more time than drawing shape. And you use a icon image represent a car, it also will cost more time than normal symbol.
12. Can you email the loading code for the layers so we can check them out.

My code want to achieve follows goal: 

1. When I input long/lat, the image will located in the center of Map. ( focus_b_Click()) 

2. When I located on the Map, I will search location informaion (ex. county name, town name, and road name) (Spatial Query→NodeQuery→Check_CrossRoad) 

3. Of course, it have to move map and query location information quickly!

Now, I have some problem about speed 

When I load the Map and pan it, it run about 1~2 second (you can see 1.jpg) 

But it is so strange, if I Zoom in or Zoom out about twice and more, the speed of pan is slower...(actually, it have to run fast. because it has no much information on the map) 

(Zoom out in 2.jpg) 

(Zoom in in 3.jpg)

Your answer is not according to questions, the work flow which you described is not loading code, Do you know what is“Loading code”? the code mostly is in formload or pageload, you can refer our HowDoI samples, and tell us what your code. The important part is how you set your zoom level and style.  Like you said, if you keep zoom in , there is no much information on the map but it run slower. The reason probably caused the wrong code for loading. 
So can you give me the loading code?.



 
13. Are you projecting any of the data? No Answer. That means you are not projecting any of the data

Thanks


James



Thanks a lot, James


I attach code file as below.


Thanks. :)


Carol


 



1446-load.txt (49.4 KB)

 


Carol.
 
Yes, your problem is caused by “loading code”, you have more than 30 layers, most of them you set the style in  a very wide zoom level range,  I think you don’t need do like that, because like you said in pic3 of screen-shot, the drawing time is much slower than normal, I think you set many unnecessary styles in that zoom level, so can you check which zoom level of pic3, and according to that zoom level you can remove some unnecessary styles to make the speed up.
 
The layer drawing order is according to the sequence of adding layers to overlay, so if layerA is added before layerB, layerA will draw first, and layerB will draw on the top of layerA, if layerB is totally cover layerA, layerA is unnessary at this zoom level, it just waste of time, because even it will draw, but you can not see the shape. And I find that you have so many roads shape files, the United States just has 7 kinds of roads which separated by CFCC, such as highway, major road, local road. So I think maybe your roads files represent the same road, but different precision, some has more vertices, some has less vertices.
 
About how to get zoom level, you can look at following steps:
Use winforms.CurrentScale to get current scale, and then get current zoomlevel number by following method:
 


        private static int GetCurrentZoomLevelNumber(double currentScale)
        {
            Collection<ZoomLevel> zoomlevels = new ZoomLevelSet().GetZoomLevels();
            int zoomlevelNumber = 0;
            for (int i = 0; i < zoomlevels.Count; i++)
            {
                if (currentScale == zoomlevels[i].Scale)
                {
                    zoomlevelNumber = i;
                    break;
                }
            }
            return zoomlevelNumber;
        }

 
Thanks
James

Thanks for your suggestion, James  
  
 in order to decrease query time of road information, 
 I divide original road.shp to many shp files (according to which country road located). 
 in fact, it really improve query performance. 
 (5.x sec→0.x sec) 
  
 I will try to check and remove some unnecessary styles to make the speed up. 
  
 Carol 
  


Carol, 
  
 You’re always welcome.  
 It’s good news that you make performance better, expect more good news from you. 
  
 Thanks 
 James

Thanks very much for your suggestion, James


You are right!


I try to use few layer to decrease pan time. it runs better than before...But it still doesn't achieve I except..


I will keep test what I can improve panning speed.


and I have other questions:


 I attached a file of picture. it is strange, why many roads doesn't show their roadname? (when I use v.2.x, it shows some roadname.)


I create a new shp file by original shp file and I just get some columns in my new shp file. (I want to decrease the size of file, so I delete some columns)                                                                                                                                                                                                                             I don't know why it has error when the code runs map.refreash(). 


error message: Your input index is out of bound (i don't know what's wrong in my new shp file)



1462-road_draw.txt (2.09 KB)

Carol, 
  
 The exception is thrown by Dbf engine, two conditions will cause this problem, one is your dbf record count is wrong which not the same as shp count or index count, the other is your dbf field count is wrong. If record count or field count out of input index, it will throw that exception. 
  
 So can you check your dbf file and make sure it’s right. Maybe you can rebuild shape files to solve this problem. 
 If you still have problem, please send your wrong dbf file and related .shp .shx files. 
  
 Thanks 
 James

Thanks for your reply, James


I will recreate shp file and try it.


other question...

Why roadname can't show ...


it always shows  when I zoom in zoomlevel19,20..


I attach the code as follows.




1464-road_.txt (1.59 KB)

 


Carol,
 
I am glad to answer your more questions.
 
You said the label always shows in zoom level 19, 20, so how about 17, 16 .15. 14, 13, 12 or else, are they also can not show?. From your code, I found that you just set the text style from zoom level 12 to 20, so if current scale is between zoom level 1 and 11, it can not show labels. Can you check your current zoom level number by my method which I told you at previous reply?
 
Or you can try to set the rules which how to show labels for text style as following code:
 
            NewRoad.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.TextLineSegmentRatio = double.MaxValue
            NewRoad.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.OverlappingRule = LabelOverlappingRule.AllowOverlapping
            NewRoad.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.DuplicateRule = LabelDuplicateRule.UnlimitedDuplicateLabels
            NewRoad.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20

 
Please let me know you have more questions
 
Thanks
James

Thanks for your reply, James 
  
 the picture shows in zoomlevel15, I don’t know why roadname can’t show  
  
 i try to use your code to test, some roadnames can show on the road. 
 does it have to use by default textstyle? 


Carol,


In zoom level 15, the roads crowd together, so the text will overlap or duplicate, some road segment is too long or too short, many reason can cause the text will be filter off.


The default text style and custom style is the same if you just set one text style. Custom styles has advantage is that it can set two or more styles.


I modified your code that you can see how to set properties of text style.


        Dim NewRoad As ShapeFileFeatureLayer = New ShapeFileFeatureLayer("D:\GIS\newroad.shp")
        Dim textStyle As TextStyle = TextStyles.CreateSimpleTextStyle("adr", "·s²Ó©úÅé", 12, DrawingFontStyles.Bold, GeoColor.StandardColors.Black, GeoColor.StandardColors.Gray, 0, 0, 3)
        textStyle.TextLineSegmentRatio = Double.MaxValue
        textStyle.OverlappingRule = LabelOverlappingRule.AllowOverlapping
        textStyle.DuplicateRule = LabelDuplicateRule.UnlimitedDuplicateLabels

        NewRoad.ZoomLevelSet.ZoomLevel18.CustomStyles.Add(textStyle)
        NewRoad.ZoomLevelSet.ZoomLevel18.CustomStyles.Add(GetLineStyle())
        NewRoad.ZoomLevelSet.ZoomLevel18.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20

        NewRoad.ZoomLevelSet.ZoomLevel17.CustomStyles.Add(textStyle)
        NewRoad.ZoomLevelSet.ZoomLevel17.CustomStyles.Add(GetSmallLineStyle())
        NewRoad.ZoomLevelSet.ZoomLevel17.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level17


        NewRoad.ZoomLevelSet.ZoomLevel16.CustomStyles.Add(textStyle)
        NewRoad.ZoomLevelSet.ZoomLevel16.CustomStyles.Add(GetSmallRareLineStyle())
        NewRoad.ZoomLevelSet.ZoomLevel16.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level16

        NewRoad.ZoomLevelSet.ZoomLevel12.CustomStyles.Add(textStyle)
        NewRoad.ZoomLevelSet.ZoomLevel12.CustomStyles.Add(GetSmallRare_LineStyle())
        NewRoad.ZoomLevelSet.ZoomLevel12.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level15

Please let me know if you have more questions


Thanks


James