ThinkGeo Basics: Debugging Tips
This is the fourth post in our ‘ThinkGeo Basics’ series. In previous articles, we have discussed Feature Sources, Styles, and Layers and Overlays. Today we’ll review some common coding mistakes and learn what to do if you’re map is not rendering the way you expect.
If you've ever added a new layer to a map only to find the display stubbornly remains blank, or an exception is thrown, you're not alone. These troubleshooting steps can help you fix such issues effectively:
Verify that your data has been correctly loaded into the Layer's FeatureSource.
Confirm that your MapUnit is correct.
Ensure that your Styling is applied correctly.
Check for Exceptions
Inspect Http Requests (on web-based Layers and Overlays)
Verify that your data has been correctly loaded into the Layer's FeatureSource.
When your map isn’t rendering any features, the first thing to double-check is the FeatureSource that we first discussed in a previous blog post here. All ThinkGeo vector layers inherit from the base FeatureLayer class which has a FeatureSource property. The FeatureSource class has 2 methods that can quickly tell us if the Layer has successfully loaded its features. To see all features in the layer, use the GetAllFeatures function. And to see all Features in the map’s current extent, use the GetFeaturesInsideBoundingBox function.
The code below shows an example of using both methods to inspect the Features in a sample ShapeFileFeatureLayer:
You can then drop a breakpoint in the code above and inspect the allFeatures and visibleFeatures variables to confirm that the features have valid geometric coordinates in your expected format and that the ColumnValues data is loaded how you expect:
Once your FeatureSource data looks good, it’s time to move onto the next debugging step and check out the MapUnit.
Confirm that your MapUnit is correct.
Every ThinkGeo map has MapUnit property that must be set to the GeographyUnit that your shapes are stored in. The most popular map units are GeographyUnit.DecimalDegree and GeographyUnit.Meter. An example of setting a map’s unit to Meter is shown below:
In the FeatureSource debugging screenshot in the previous section, the multipolygon Features have vertex lat/lon values that are very high such as 2484617. This is a good indication that this Layer contains features that are measured in Meter. If your lat/lon values were between -180 and 180 or -90 and 90, then that would typically indicate the Layer’s features are measured in Decimal Degree.
Depending on how your map is coded, specifying an incorrect MapUnit can result in the following wide range of errors:
Features displayed in incorrect locations.
Features displayed at an incorrect scale.
The entire map can be blank.
An exception is thrown or rendered when rendering the map.
Ensure that your styling is applied correctly.
Once your FeatureSource is loaded and MapUnit is set correctly, you will still not see any features on the map unless you apply the appropriate Styles. In our earlier Styles blog post, we discussed the four major types of styles (LineStyles, AreaStyles, PointStyles and TextStyles). If you need a refresher, you can view that blog post here. The main thing to remember is that you must use the correct style based on your data type. If you have polygon data in your FeatureSource, and choose to use a PointStyle or LineStyle, nothing will be rendered on the map. If your FeatureSource contains Line data, you’ll need to use a LineStyle to display it.
You’ll also want to make sure your Style is applied to the correct ZoomLevels. For example, if you’ve configured your style for just ZoomLevel10 to ZoomLevel20 and your map is zoomed out at the world view, you will not see any features rendered on the map.
Once you are confident that your styles are configured properly, you can move on to checking for any Exceptions.
Check for Exceptions
By default, every ThinkGeo Overlay and Layer is set to DrawingExceptionMode.Default which will throw exceptions that occur in the main thread of the map (and render exceptions that occur in separate tile threads). If your application has a try/catch block around the map, make sure to check for any exceptions in the catch block. If you want to force the map to display all exceptions on the map itself, you can set this property to DrawingExceptionMode.DrawException as seen below:
Setting this property will result in output similar to the image below with the text of “The file specified does not exist“. In the example below, we loaded a ShapefileFeatureLayer with an incorrect path to the .shp file:
You can also switch the exception mode to DrawingExceptionMode.ThrowException and use the ThrowingException event (new in 13.2) to debug and log the exception:
Inspect Http Requests (on web-based Layers and Overlays)
If you’re having issues with a Web-Based Layer or Overlay (WMS, WMTS, ThinkGeo Cloud, Google, MapBox, Bing, OSM, etc.) a great debugging tool is the SendingWebRequest event. You can create your own event handler to hook into this event and each time a web request is made to the server, the event will trigger your handler and you can inspect the SendingWebRequestEventArgs parameter. Note: in the upcoming 13.2 release, these will be deprecated and replaced with SendingHttpRequest and SendingHttpRequestMessageEventArgs.
The code below shows an example of handling the SendingWebRequest event and writing out the RequestUri to Debug. This can be very helpful to learn exactly what the Layer or Overlay is sending on each request and learn which parameters may be incorrect or missing. You can also take the RequestUri value and paste it in your browser to confirm that there are no network or firewall issues.
Using the ThinkGeoDebugger Class
The new MAUI control is also introduces new debugging features to help developers better diagnose issues. While this feature was introduced with the v14 MAUI release, it is implemented in the ThinkGeo.Core namespace and can be used across all ThinkGeo components.
The new ThinkGeoDebugger class exposes internal ThinkGeo debugging information directly to your Logs and Map. The code snippet below shows a sample usage and we’ll go into details on each property below.
// Enabling theDisplayTileId property will result in the TileIds being drawn to the map.
// This is useful when debugging tile performance and tile order in custom layers and overlays.
ThinkGeoDebugger.DisplayTileId = true;
// The LogLevel property determines the verbosity of logs you wish to view in your output.
ThinkGeoDebugger.LogLevel = ThinkGeoLogLevel.All;
// The LogType property allows you to specify which internal Turn on all Logging
ThinkGeoDebugger.LogType = ThinkGeoLogType.All;
// Or just enable certain Log Types:
ThinkGeoDebugger.LogType = ThinkGeoLogType.WebRequest | ThinkGeoLogType.Rendering;
The first property to note is the DisplayTileId. When set to true, the internal TileIds will be drawn to the map. This is useful when debugging tile performance and tile order in custom layers and overlays. The screenshot to the right shows the map with the DisplayTileIds property set to true which results in each tile being outlined and labeled in red.
The next property of interest is the LogType. You can assign multiple ThinkGeoLogType enum values to this property. From Rendering and Caching to WebRequests and Interaction, you can find a lot of information about the internals of the map. In the code snippet above, the LogType is set to ThinkGeoLogType.WebRequest and ThinkGeoLogType.Rendering. The result is debug output similar to the screenshot below:
Finally, there is also a LogLevel property. You can set this property to a value from the ThinkGeoLogLevel enum and the results are self-explanatory and function like any other logging package.
Conclusion
We hope you’ve found this post helpful. If you have any other tips you would like for us to add to this post, please email support@thinkgeo.com. We would love to hear your thoughts and continue to improve this article over time.
If you are new to ThinkGeo and want to see our maps in action, the first step is to sign up for a free evaluation and download our Gitlab samples here!