ThinkGeo.com    |     Documentation    |     Premium Support

Problem with CheckOverlapping method in TextStyle

I am upgrading from TG-10 to TG-14. The version of CheckOverlapping I was using in my CustomTextStyle class (inherits from TextStyle) has been deprecated and I cant’ seem to make the current version work. Here is the code:

      Dim oQuadTree As New Quadtree(Of SimpleCandidate)
      If CheckOverlapping(oLabelingCandidate, oCanvas, Me.Font, Me.XOffsetInPixel, Me.YOffsetInPixel, Me.RotationAngle, oQuadTree) Then
        '***** It would overlap another label so don't add it.
        Continue For
      End If

I receive the following:

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=ThinkGeo.Core
  StackTrace:
   at ThinkGeo.Core.PositionStyle.CheckOverlapping(LabelingCandidate labelingCandidate, GeoCanvas canvas, GeoFont font, Single xOffsetInPixel, Single yOffsetInPixel, Double rotationAngle, Quadtree`1 labelsInAllLayersIndex)
   at ThinkGeo_14_Demo.CustomTextStyle.GetLabeledFeatures(Collection`1 oAllFeatures, GeoCanvas oCanvas, Collection`1 labelsInThisLayer, Collection`1 labelsInAllLayers) in C:\Users\ZipPa\source\repos\LabelTest\CustomTextStyle.vb:line 829

I may not be using it correctly as I have never used QuadTree(of T) before. I have attached a sample project. Look in class CustomTextStyle in method GetLabeledFeatures for the exception.

Thanks,

Steve
LabelTest.zip (2.3 MB)

Hi Steve,

The following 2 changes on your side would make it work:

  1. Set Feature (and some other properties right after GetLabelingCandidates)
	Dim oRawLabelingCandidates As Collection(Of LabelingCandidate) = GetLabelingCandidates(oFeature, FormatTemplate(Me.TextContent, oFeature.ColumnValues), oCanvas, Me.Font, XOffsetInPixel, YOffsetInPixel, RotationAngle)
	For i As Integer = 0 To oRawLabelingCandidates.Count - 1
		oRawLabelingCandidates(i).Feature = oFeature
		oRawLabelingCandidates(i).PositionStyle = Me
		oRawLabelingCandidates(i).Key = oRawLabelingCandidates(0).OriginalText & Me.GetHashCode().ToString()
	Next
...... 

These assignments are in DrawCore which were not called by you. We are going to move these code over to GetLabelingCandidates since beta080 so you will not need these workaround code in the future.

  1. In the constructor of CustomLabelingCandidate, Add “Feature = oLabelingCandidate.Feature”
	Public Sub New(oLabelingCandidate As LabelingCandidate, iLabelingId As Integer)
		MyBase.New
		With oLabelingCandidate
            ......
			Feature = oLabelingCandidate.Feature
		End With
		LabelingId = iLabelingId
	End Sub

Let me know if you see more issues.

Thanks,
Ben

FYI: ThinkGeo.UI.WinForms 14.5.0-beta080 was just uploaded.

Ben,

Thanks very much for the help and the quick response. I no longer receive an error but CheckOverlapping is not detecting overlapping labels. I am still doing something wrong and I think it has to do with Quadtree. I am simply passing an empty Quadtree to the function. Shouldn’t it be initialized with labelsInThisLayer and labelsInAllLayers?

Thanks!

Steve

Hi Steve,

The quadtree index is initialized inside TextStyle.DrawCore . Since you’ve overridden TextStyle.DrawCore , that initialization no longer happens automatically, so you’ll need to initialize the quadtree index yourself.

That said, you may not need to override TextStyle.DrawCore at all. In most cases, it’s better to override the more granular methods instead.

TextStyle.DrawCore performs the following steps:

  1. Filters the features to be rendered
    – Customizable by overriding FilterFeaturesCore
  2. For each filtered feature:
    2.1 Gets the labeling text
    – Customizable by overriding GetLabelingTextCore
    2.2 Gets labeling candidates
    – Customizable by overriding GetLabelingCandidateCore
  3. For each labeling candidate:
    3.1 Checks for duplicates
    – Customizable by overriding CheckDuplicateCore
    3.2 Checks for overlapping
    – Customizable by overriding CheckOverlappingCore (This method receives the quadtree index as a parameter.)
    3.3 Draws the text
    – Customizable by overriding DrawTextCore

By overriding these smaller methods, you can customize the labeling behavior without having to re-implement the full DrawCore logic, including quadtree initialization.

Have a try and let me know if you have any problems.

Thanks,
Ben

Thanks, looks like that should work well.

How do you initialize the quadtree index?

Thanks!

Steve

Here is the code in TextStyle.DrawCore:

     var allLabelsIndex = new Quadtree<SimpleCandidate>();
     foreach (var label in labelsInAllLayers)
     {
         var envelop = label.EnvelopeInScreenCoordinate;
         allLabelsIndex.Insert(envelop, label);
     }

and this qtree index passes into the methods in #3 in the above list.