ThinkGeo.com    |     Documentation    |     Premium Support

Display distance info of line with custom style

Hello,


we draw lines representing railways. We need to display distance info according to length of the line. Length of segment to display the distance can be by the User.  I imagine I can do this with a custom style.


Is this the right way? Any samples?


Thanks Thomas


Samples:


|----------|----------|----------|----------|


0km                                                 4km


|----------|----------|----------|----------|


0m        50m       100m   150m    200m



Thomas,


Sorry for the delay, I am trying to find a similar project which customized a LineStyle, unfortunately failed. Your requirement logic seems a bit complicated.
 
I think the customized style is definitely the right direction. Following post shows some code with customized area style to gain some effects.
gis.thinkgeo.com/Support/Dis...fault.aspx
 
Besides, following posts shows some insights from David about customized style.
gis.thinkgeo.com/Support/Dis...fault.aspx
Any more questions feel free to let me know.
 
Thanks.
 
Yale

Hello again, 
  
 we made some tests with custom style and need more informations: 
  
 1. We noticed that in the DrawCore-Method of custom line style we get passed in all line-features inside the bounding box of Map-Control. To speed up our method which creates the positions to label the distance information for the line we need to get only the part of the line that is inside the bounding box. Otherwise we have to caculate the positions for the whole line-feature -> slow drawing. Any ideas? 
  
 100m <–Label 
 |--------|--------| 
  
  
 2. To get the following result  |---------|--------| we want to create two pens. 
 InnerPen:  ------------------------ 
 OuterPen: |           |           | 
 The create the OuterPen line we want to use the DashPatter-Property. Do you have any idea how we can calculate the DashPattern-Value in our custom style to arrange the OuterPen to draw his line in relation to a distance e.g. 10m or 50m 
  
 Thomas 
  
  


Thomas,


Thanks for your post and questions.
 
Following post seems very similar to this kind of requirement, take a look if you are interested:
gis.thinkgeo.com/Support/Dis...fault.aspx
 
About the inner part of the line inside the current extent, try following logic, while I am not fully test this:
1)      Loop each line inside the boundingbox.
2)      If it is completely inside, just skip it.
3)      If it is intersects, get the intersection points. If intersection points is two points, that is fine, if it only one, try the first point or the last point if it is inside the extent. Use the API GetLineOnALine to get the intersection part.
I am not sure this can be used in some complex cases.
 
I think the GetPointOnALine API should solve your second problem.
 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

Hello ThinkGeo-Team,


after developing many functions inside our GIS-Application I come back to one of my older requests.


To get the result I desribed above I made some tests with DashPatter property but I recognized that DashPattern parameters do not depend on any distance information of the drawing shape .


So I tried to implement it by using some distance functions(). I have attached a small sample application where you can see a first simple version of my custom style. As you can see in the sample my custom style has one problem:

If you zoom in, the line to mark the position of the distance is expanded because the length of my line is not getting smaller addicted to zoomlevel scale.


I dont know if there are any other options to get my result. May be there is a better (faster) solution. Can you point me in the right direction?


Thomas



GIS_Kilometrierung.zip (64.1 KB)

Thomas,


 I am getting late into the conversation but I would like to just interject something. We have a Code Community sample called Distance LineStyle that I think you should like and it should get you inspire for your own case. I want to make sure you have not missed this resource. wiki.thinkgeo.com/wiki/Map_Suite_Se...Line_Style


 If you are still at lost, I will get more specifically in the details of your case as I have experience dealing with unusual requests for styling lines.


Thank you.



Hello Val,


thanks for information. I made some changes to my custom style. But I still do not know how to resolve the drawing issue of my perpendicular reference line elements. When zooming in the reference lines get longer and overwrite the text style area.


This is a very annoying effect. Do you have any suggestions?


Thomas


 



GIS_Kilometrierung2.zip (77.8 KB)

Thomas,


 You need to change the logic in the DrawCore function so that the perpenticular reference lines are drawn at a constant length in screen coordinates. And for that you need to use the ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints which is going to give you the world distance for a given screen width. The world distance is going to change at each new zoom level but the line length (5 pixels in this case) is going to remain constant as you can see in the screen shots:




 


This is the code for your cCustomStyleStationInfo.vb that I modified:


 



Imports ThinkGeo.MapSuite.Core

Public Class cCustomStyleStationInfo
    Inherits ThinkGeo.MapSuite.Core.LineStyle

    Protected Overrides Sub DrawCore(ByVal features As System.Collections.Generic.IEnumerable(Of ThinkGeo.MapSuite.Core.Feature), ByVal canvas As ThinkGeo.MapSuite.Core.GeoCanvas, ByVal labelsInThisLayer As System.Collections.ObjectModel.Collection(Of ThinkGeo.MapSuite.Core.SimpleCandidate), ByVal labelsInAllLayers As System.Collections.ObjectModel.Collection(Of ThinkGeo.MapSuite.Core.SimpleCandidate))
        MyBase.DrawCore(features, canvas, labelsInThisLayer, labelsInAllLayers)

        Dim oDrawingLineShape As ThinkGeo.MapSuite.Core.LineShape
        Dim oLinePoint As ThinkGeo.MapSuite.Core.PointShape
        Dim oLineShape As ThinkGeo.MapSuite.Core.LineBaseShape
        Dim oLineStyle As ThinkGeo.MapSuite.Core.LineStyle = ThinkGeo.MapSuite.Core.LineStyles.CreateSimpleLineStyle(ThinkGeo.MapSuite.Core.GeoColor.SimpleColors.Black, 1.0F, False)
        Dim oTangente As ThinkGeo.MapSuite.Core.LineShape
        Dim oScreenPointF As ThinkGeo.MapSuite.Core.ScreenPointF
        Dim dblWinkel As Double
        Dim decDistance As Decimal = 0D
        Dim dblOffset As Double

        oDrawingLineShape = DirectCast(features(0).GetShape, ThinkGeo.MapSuite.Core.LineShape)

        Do Until decDistance > oDrawingLineShape.GetLength(ThinkGeo.MapSuite.Core.GeographyUnit.Meter, ThinkGeo.MapSuite.Core.DistanceUnit.Kilometer)

            oLinePoint = oDrawingLineShape.GetPointOnALine(ThinkGeo.MapSuite.Core.StartingPoint.FirstPoint, Convert.ToSingle(decDistance), ThinkGeo.MapSuite.Core.GeographyUnit.Meter, ThinkGeo.MapSuite.Core.DistanceUnit.Kilometer)

            oTangente = cGISHelper.ermittleTangenteFuerLinienposition(oDrawingLineShape, decDistance)
            dblWinkel = cGISHelper.GetAngleFromTwoVertices(oTangente.Vertices(0), oTangente.Vertices(1))

            dblWinkel += 90.0
            If dblWinkel >= 360.0 Then
                dblWinkel = dblWinkel - 180
            End If

            oScreenPointF = ThinkGeo.MapSuite.Core.ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, oLinePoint, canvas.Width, canvas.Height)

            canvas.DrawText("    " + decDistance.ToString, New ThinkGeo.MapSuite.Core.GeoFont("Arial", 12, ThinkGeo.MapSuite.Core.DrawingFontStyles.Bold), _
                            New ThinkGeo.MapSuite.Core.GeoSolidBrush(ThinkGeo.MapSuite.Core.GeoColor.StandardColors.Black), _
                            New ThinkGeo.MapSuite.Core.GeoPen(ThinkGeo.MapSuite.Core.GeoColor.StandardColors.White), _
                            New ThinkGeo.MapSuite.Core.ScreenPointF() {oScreenPointF}, ThinkGeo.MapSuite.Core.DrawingLevel.LabelLevel, _
                            0.0F, 0.0F, Convert.ToSingle(dblWinkel))

            If decDistance = 0D Then
                dblOffset = 0.0
            Else
                dblOffset = 0.001
            End If


            'oLineShape = oDrawingLineShape.GetLineOnALine(ThinkGeo.MapSuite.Core.StartingPoint.FirstPoint, decDistance - dblOffset, 0.002, ThinkGeo.MapSuite.Core.GeographyUnit.Meter, ThinkGeo.MapSuite.Core.DistanceUnit.Kilometer)

            Dim dblTranslateAngle = cGISHelper.ermittleOrthogonalWinkelZuVertex(oTangente.Vertices(0), oTangente.Vertices(1), cGISHelper.EGleislage.Links)

            '------YOUR OLD CODE-----------------------------------------
            'Dim oPoint2 As ThinkGeo.MapSuite.Core.PointShape = DirectCast(ThinkGeo.MapSuite.Core.BaseShape.TranslateByDegree(oLinePoint, 20.0, dblTranslateAngle, ThinkGeo.MapSuite.Core.GeographyUnit.Meter, ThinkGeo.MapSuite.Core.DistanceUnit.Meter), ThinkGeo.MapSuite.Core.PointShape)

            'oLineShape = New ThinkGeo.MapSuite.Core.LineShape(New ThinkGeo.MapSuite.Core.Vertex() {New ThinkGeo.MapSuite.Core.Vertex(oLinePoint), New ThinkGeo.MapSuite.Core.Vertex(oPoint2)})

            'oLineStyle.Draw(New ThinkGeo.MapSuite.Core.BaseShape() {oLineShape}, canvas, labelsInThisLayer, labelsInAllLayers)

            '-----MY NEW CODE--------------------------------------------------------------------------------------------------------------------------------
            Dim worldDist As Double = ExtentHelper.GetWorldDistanceBetweenTwoScreenPoints(canvas.CurrentWorldExtent, 0, 0, 5, 0, canvas.Width, canvas.Height, GeographyUnit.Meter, DistanceUnit.Meter)
            Dim oPoint2 As PointShape = DirectCast(BaseShape.TranslateByDegree(oLinePoint, worldDist, dblTranslateAngle, ThinkGeo.MapSuite.Core.GeographyUnit.Meter, ThinkGeo.MapSuite.Core.DistanceUnit.Meter), ThinkGeo.MapSuite.Core.PointShape)
            oLineShape = New ThinkGeo.MapSuite.Core.LineShape(New ThinkGeo.MapSuite.Core.Vertex() {New ThinkGeo.MapSuite.Core.Vertex(oLinePoint), New ThinkGeo.MapSuite.Core.Vertex(oPoint2)})

            oLineStyle.Draw(New ThinkGeo.MapSuite.Core.BaseShape() {oLineShape}, canvas, labelsInThisLayer, labelsInAllLayers)


            decDistance += 0.1D

        Loop

    End Sub

End Class


Hello Val, 
  
 thanks a lot for your sample code. I will continue working on my implementation. 
  
 Thomas 


Thomas,


Thanks for your updating your status.


I will also keep an eye on this thread, so just feel free to post any questions you encouter when you implement.


Thanks,


James



Thomas,


 We let you know that we posted a Code Community sample based on your idea for distance info line style, Line Style With Incrementwiki.thinkgeo.com/wiki/Map_Suite_De..._Increment. Thank you for your participation.