ThinkGeo.com    |     Documentation    |     Premium Support

Graticule labeling problem in polar stereographic projection

Hi,
I am not able to set proper graticule label in polar stereographic projection.
But, it’s work out in ‘Mercator’ projection.

I tried to set graticule labels in different ways.
1.
GraticuleAdornmentLayer graticuleAdornmentLayer = new GraticuleAdornmentLayer();
graticuleAdornmentLayer.Projection = _proj;
graticuleAdornmentLayer.GraticuleLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.SimpleColors.Silver, 0.001F, LineDashStyle.Dash, false);
wfMap.AdornmentOverlay.Layers.Add(“GraticuleAdornmentLayer”, graticuleAdornmentLayer);

ShapeFileFeatureLayer shplatlon1 = new ShapeFileFeatureLayer(@"…/…/Data/Graticule/graticules_1.shp");
shplatlon1.FeatureSource.Projection = _proj;
shplatlon1.RequireIndex = false;
shplatlon1.ZoomLevelSet.ZoomLevel10.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.SlateGray, 0.001F));
shplatlon1.ZoomLevelSet.ZoomLevel10.DefaultTextStyle = new TextStyle(“display”, new GeoFont(“Arial”, 20), new GeoSolidBrush(GeoColors.Red));
shplatlon1.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

        ShapeFileFeatureLayer shplatlon5 = new ShapeFileFeatureLayer(@"../../Data/Graticule/graticules_5.shp");
        shplatlon5.FeatureSource.Projection = _proj;
        shplatlon5.RequireIndex = false;
        shplatlon5.ZoomLevelSet.ZoomLevel07.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.SlateGray, 0.001F));
        shplatlon5.ZoomLevelSet.ZoomLevel07.DefaultTextStyle = new TextStyle("display", new GeoFont("Arial", 20), new GeoSolidBrush(GeoColors.Red));
        shplatlon5.ZoomLevelSet.ZoomLevel07.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level10;

        ShapeFileFeatureLayer shplatlon10 = new ShapeFileFeatureLayer(@"../../Data/Graticule/graticules_10.shp");
        shplatlon10.FeatureSource.Projection = _proj;
        shplatlon10.RequireIndex = false;
        shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.SlateGray, 0.001F));
        shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = new TextStyle("display", new GeoFont("Arial", 20), new GeoSolidBrush(GeoColors.Red));
        shplatlon10.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level07;

        ShapeFileFeatureLayer shapeBoundary = new ShapeFileFeatureLayer(@"../../Data/Graticule/graticules_boundary.shp");
        shapeBoundary.FeatureSource.Projection = _proj;
        shapeBoundary.RequireIndex = false;
        shapeBoundary.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.SlateGray, 0.001F));
        shapeBoundary.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level07;

        LayerOverlay latlonOverlay = new LayerOverlay();
        latlonOverlay.Layers.Add("Graticule1", shplatlon1);
        Overlay.Layers.Add("Graticule5", shplatlon5);
        latlonOverlay.Layers.Add("Graticule10", shplatlon10);
        latlonOverlay.Layers.Add("GraticuleBoundary", shapeBoundary);
        wfMap.Overlays.Add("GraticuleOverlay", latlonOverlay);

Here, I am attaching snapshots of my application.

help me to fix this issue.

Thanks,
Riyaz

Hi Riyaz,

Could you please give us more detail description about the issue you met?

From your screen shots and your text we cannot find where is the problem.

Regards,

Don

Hi Don,
Actually I want to display ‘latitude longitude’ of each graticule on the map in ‘PSG’ projection.
Look at last image i sent previous, In that graticules are plotted correctly. but there is no lat lon label points.

I want like this…

just referred ‘Showing Latitude Longitude graticule on the map’ article. but there is no code to do it.

give me some suggestions to achieve it.

Hi Riyaz,

You have 3 screen captures in your post, it looks only the last one don’t have the text style.

I think that’s maybe related with the projection convert, I suggest you test some properties for .DefaultTextStyle, for example:

.DefaultTextStyle.TextLineSegmentRatio = 2;
.DefaultTextStyle.SuppressPartialLabels = true;
.DefaultTextStyle.GridSize = 5;
.DefaultTextStyle.DuplicateRule = LabelDuplicateRule.UnlimitedDuplicateLabels;
.DefaultTextStyle.OverlappingRule = LabelOverlappingRule.AllowOverlapping;

You can try to modify their value and see whether you can get a better text render result.

Wish that’s helpful.

Regards,

Don

Hi Don,
I tried by your code.But it’s not work out.
I am attaching sample application and data.could you please check and solve this issue.

Thanks,
Riyaz
GraticuleLabelforPSG.zip (4.9 KB)
Graticule.zip (1.3 MB)

Hi Riyas,

It looks that’s because your line it too long for the special projection, so most parts of a graticule line is out of extent.

If possible, please split the line to smaller segments for get a better result, or you can modify my code as below to make it rendered. I did a test for your data with the modified code today but it looks the result maybe not the best.

 public class MyTextStyle : TextStyle
{
    public MyTextStyle(string textColumnName, GeoFont textFont, GeoSolidBrush textSolidBrush)
        : base(textColumnName, textFont, textSolidBrush)
    {
    }

    protected override Collection<LabelingCandidate> GetLabelingCandidateCore(Feature feature, GeoCanvas canvas)
    {
        Collection<LabelingCandidate> candiateLabels = base.GetLabelingCandidateCore(feature, canvas);


        ScreenPointF upperLeft = ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, canvas.CurrentWorldExtent.UpperLeftPoint, canvas.Width, canvas.Height);
        ScreenPointF lowerRight = ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, canvas.CurrentWorldExtent.LowerRightPoint, canvas.Width, canvas.Height);
        RectangleShape screenExtent = new RectangleShape(upperLeft.X, lowerRight.Y, lowerRight.X, upperLeft.Y);

        for (int i = 0; i < candiateLabels.Count; i++)
        {
            if (!candiateLabels[i].CenterPoint.IsWithin(screenExtent))
            {
                MultilineShape featureInScreen = (feature.GetShape() as MultilineShape).GetIntersection(screenExtent);
                if (featureInScreen.Lines.Count > 0)
                {
                    LineShape theLineInScreen = featureInScreen.Lines[0] as LineShape;

                    PointShape centerPoint = theLineInScreen.GetCenterPoint();

                    LabelInformation labelInfo = candiateLabels[i].LabelInformation[0];
                    labelInfo.PositionInScreenCoordinates = centerPoint;
                    Collection<LabelInformation> labelInformationCollection = new Collection<LabelInformation>();
                    labelInformationCollection.Add(labelInfo);

                    int offset = 10;

                    PolygonShape polygon = new RectangleShape(centerPoint.X - offset, centerPoint.Y + offset, centerPoint.X + offset, centerPoint.Y - offset).ToPolygon();

                    candiateLabels[i] = new LabelingCandidate(candiateLabels[i].OriginalText, polygon, centerPoint, labelInformationCollection);
                }
            }
        }


        return candiateLabels;
    }

}

 ShapeFileFeatureLayer.BuildIndexFile(@"../../Data/Graticule/graticules_10.shp", BuildIndexMode.DoNotRebuild);
        ShapeFileFeatureLayer shplatlon10 = new ShapeFileFeatureLayer(@"../../Data/Graticule/graticules_10.shp");
        shplatlon10.FeatureSource.Projection = _proj;
        //shplatlon10.RequireIndex = false;

        shplatlon10.FeatureSource.Open();
        Collection<Feature> fts10 = shplatlon10.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
        shplatlon10.FeatureSource.Close();


        shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.Black, 0.001f));



        shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = new MyTextStyle("display", new GeoFont("Arial", 10), new GeoSolidBrush(GeoColors.Red));

        shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.TextLineSegmentRatio = 300;
        //shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.SuppressPartialLabels = true;
        //shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.GridSize = 100;
        shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.DuplicateRule = LabelDuplicateRule.UnlimitedDuplicateLabels;
        shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.OverlappingRule = LabelOverlappingRule.AllowOverlapping;
        //shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.LabelAllLineParts = true;
        shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.SplineType = SplineType.StandardSplining;

        //shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.BestPlacement = true;



        shplatlon10.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level07;

Any question please let us know.

Regards,

Don

Hi Don,

      Thanks for your code. 

The labels are coming correctly for ‘LAT’ values.But, for ‘LONG’ values.it’s not coming correctly.
pls check and correct it.

Thanks,
Riyaz

Hi Riyaz,

Just like I mentioned in my previous reply, the mainly issue comes from Longitude lines, they are too long for the special projection so I can just make they shown but cannot make them shows correct by this way.

Do you think it’s possible to do an optimization for this data to split the long longitude line to lots of short segments?

And I will go on trying to help you to make the label looks better when I get time today, if I get any good news I will let you know.

Regards,

Don

Hi Don,
Yes. It’s problem in the Long lines showing on PSG projection. I am trying to Split Line up to the current extent.

Please you also try solve this issue. Once you solved, Let us know about it.

Thanks,
Riyaz

Hi Riyaz,

I checked the source and found that there is an issue. Please try using “UnmanagedProj4Projection” instead of “ManagedProj4Projection” the code maybe like below:

 _proj = new UnmanagedProj4Projection();
  _proj.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(4326);
  _proj.ExternalProjectionParametersString = "+proj=stere +lat_0=90 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m no_defs";

For the ‘LONG’ labels are not correct, I guess there are 2 options for this.

  • Use the following code to draw the labels with version 9.0.372.0 or later, and the following is the screenshot.

     private void LoadGraticules()
     {
        
         ShapeFileFeatureLayer shplatlon1 = new ShapeFileFeatureLayer(@"../../Data/Graticule/graticules_1.shp");
         shplatlon1.FeatureSource.Projection = _proj;
         shplatlon1.RequireIndex = false;
    
         shplatlon1.FeatureSource.Open();
         Collection<Feature> fts1 = shplatlon1.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
         shplatlon1.FeatureSource.Close();
    
         shplatlon1.ZoomLevelSet.ZoomLevel10.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.SlateGray, 0.001F));
         shplatlon1.ZoomLevelSet.ZoomLevel10.DefaultTextStyle = new TextStyle("display", new GeoFont("Arial", 20), new GeoSolidBrush(GeoColors.Red));
         shplatlon1.ZoomLevelSet.ZoomLevel10.DefaultTextStyle.TextLineSegmentRatio = 200000; // The line is to long and we need to set this value large enough
         shplatlon1.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.FittingLineInScreen = true;
         shplatlon1.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.YOffsetInPixel = 50;
         shplatlon1.ZoomLevelSet.ZoomLevel10.DefaultTextStyle.DuplicateRule = LabelDuplicateRule.NoDuplicateLabels;
         shplatlon1.ZoomLevelSet.ZoomLevel10.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
    
         ShapeFileFeatureLayer shplatlon5 = new ShapeFileFeatureLayer(@"../../Data/Graticule/graticules_5.shp");
         shplatlon5.FeatureSource.Projection = _proj;
         shplatlon5.RequireIndex = false;
    
         shplatlon5.FeatureSource.Open();
         Collection<Feature> fts5 = shplatlon5.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
         shplatlon5.FeatureSource.Close();
    
         shplatlon5.ZoomLevelSet.ZoomLevel07.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.SlateGray, 0.001F));
         shplatlon5.ZoomLevelSet.ZoomLevel07.DefaultTextStyle = new TextStyle("display", new GeoFont("Arial", 20), new GeoSolidBrush(GeoColors.Red));
         shplatlon5.ZoomLevelSet.ZoomLevel07.DefaultTextStyle.TextLineSegmentRatio = 2000000;
         shplatlon5.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.YOffsetInPixel = 50;
         shplatlon5.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.FittingLineInScreen = true;
         shplatlon5.ZoomLevelSet.ZoomLevel07.DefaultTextStyle.DuplicateRule = LabelDuplicateRule.NoDuplicateLabels;
         shplatlon5.ZoomLevelSet.ZoomLevel07.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level10;
    
         ShapeFileFeatureLayer shplatlon10 = new ShapeFileFeatureLayer(@"../../Data/Graticule/graticules_10.shp");
         shplatlon10.FeatureSource.Projection = _proj;
         shplatlon10.RequireIndex = false;
    
         shplatlon10.FeatureSource.Open();
         Collection<Feature> fts10 = shplatlon10.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
         shplatlon10.FeatureSource.Close();
    
         shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.SlateGray, 0.001F));
         shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = new TextStyle("display", new GeoFont("Arial", 20), new GeoSolidBrush(GeoColors.Red));
         shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.TextLineSegmentRatio = 2000000;
         shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.YOffsetInPixel = 50;
         shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.FittingLineInScreen = true;
         shplatlon10.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.DuplicateRule = LabelDuplicateRule.NoDuplicateLabels;
         shplatlon10.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level07;
    
         ShapeFileFeatureLayer shapeBoundary = new ShapeFileFeatureLayer(@"../../Data/Graticule/graticules_boundary.shp");
         shapeBoundary.FeatureSource.Projection = _proj;
         shapeBoundary.RequireIndex = false;
         shapeBoundary.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new LineStyle(new GeoPen(GeoColor.StandardColors.SlateGray, 0.001F));
         shapeBoundary.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level07;
    
         LayerOverlay latlonOverlay = new LayerOverlay();
         latlonOverlay.Layers.Add("Graticule1", shplatlon1);
         latlonOverlay.Layers.Add("Graticule5", shplatlon5);
         latlonOverlay.Layers.Add("Graticule10", shplatlon10);
         latlonOverlay.Layers.Add("GraticuleBoundary", shapeBoundary);
         wfMap.Overlays.Add("GraticuleOverlay", latlonOverlay);
     }
    

  • Try the way Don mentioned before(Split the long line into some short lines).

Thanks,
Peter

Hi Peter,

I changed ‘UnmanagedProj4Projection’ instead of ‘ManagedProj4Projection’.Then, I tried your code.
Lat values correctly and Long values slightly missed out.
Pls observe it.I keep on varying ‘TextLineSegmentRatio’ value.It’s not work out.

Before I tried with Don logic of ‘Split the long line into some short lines’ using ‘GetLabelingCandidateCore’ method.But I am unable to get it.

Please try to fix it.

Thanks,
Riyaz

Hi Riyaz,

I guess this issue caused by the wrong version. I fixed an issue in the version 9.0.372.0, please get it and have a try again.

Any questions please let me know.

Thanks,
Peter

Hi Peter,
I tried by latest version(9.0.401.0).even though i tried for 9.0.379.0. It’s not coming.
For 401 version, while searching a feature by

InMemoryFeatureLayer imAfc = (InMemoryFeatureLayer)wfMap.FindFeatureLayer(“CircleLayer”);
imAfc.FeatureSource.GetFeaturesByColumnValue(“name1”, “A”);

        I am getting 'KeyNotFoundException'. Probably GetFeaturesByColumnValue getting some error while searching it.

If I run in earlier versions it’s working fine.

Tell me what is the reason, How should I solve it.

Thank you,
Riyaz

Hi Riyaz,

I was unable to recreated this issue, Could you please give me more code snippets here.

Thanks,
Peter

Hi Peter,
You told me, to try with version 9.0.372.0. I tried that later versions also. But still problem there. labels are not showing properly.

In 9.0.401.0 version I found one error. it’s not coming in 9.0.63.0 and earlier versions.

Code -
InMemoryFeatureLayer imAfc = (InMemoryFeatureLayer)wfMap.FindFeatureLayer(“CircleLayer”);
if (imAfc != null)
{
Collection fAfc = imAfc.FeatureSource.GetFeaturesByColumnValue(“name1”, “A”);
if (fAfc.Count > 0)
{
wfMap.FindFeatureLayer(“CircleLayer”).FeatureSource.FeatureIdsToExclude.Add(fAfc[l].Id);
}
}
The problem in searching feature by column value (GetFeaturesByColumnValue) method.
Please check it and suggest me solving this issue?

Thank you,
Riyaz

Hi Riyaz,

Please check the answers below:

For #1, Attached is the sample shows how to display the labels.GraticuleLabelingSample.zip (4.8 KB), following the the screenshot:

For #2, I was unable to reproduce the issue about the “KeyNotFoundException”, could you provide us a sample for this. Following is my test code:

  InMemoryFeatureLayer inMemoryFeatureLayer = new InMemoryFeatureLayer();
        inMemoryFeatureLayer.InternalFeatures.Add(new Feature(new PointShape(), new Dictionary<string, string> { { "name1", "A1" } }));
        inMemoryFeatureLayer.InternalFeatures.Add(new Feature(new PointShape(), new Dictionary<string, string> { { "name1", "A2" } }));
        inMemoryFeatureLayer.InternalFeatures.Add(new Feature(new PointShape(), new Dictionary<string, string> { { "name1", "A3" } }));
        inMemoryFeatureLayer.InternalFeatures.Add(new Feature(new PointShape(), new Dictionary<string, string> { { "name1", "A4" } }));
        inMemoryFeatureLayer.InternalFeatures.Add(new Feature(new PointShape(), new Dictionary<string, string> { { "name1", "A5" } }));
        inMemoryFeatureLayer.Open();
        var result = inMemoryFeatureLayer.FeatureSource.GetFeaturesByColumnValue("name1", "A1");

Thanks,
Peter

Hi Peter,
Same functionality not coming in ‘WRF Lambert Conformal Conic’ Projection.

_proj.ExternalProjectionParametersString = “+proj=lcc +lat_1=15 +lat_2=55 +lat_0=40 +lon_0=50 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs”;

Please check and fix it?

Thanks,
Riyaz

Hi Riyaz,

For the new projection, if you have any change to the code please let us know.

If everything is the same, please tell us how to reproduce it, include your current dll version, which sample is used for that and any code need be changed in sample.

Regards,

Don