ThinkGeo.com    |     Documentation    |     Premium Support

Error adding label to InMemoryFeatureLayer: "points must form a closed linestring"

I'm trying to add a label at a calculated lat/lon position onto a PolygonShape I'm drawing on my map.  I'm using the same functional code where I add labels EllipseShape, but I get this error when I hit Map1.Refresh: "points must form a closed linestring".  If I remove the section of code for the label, all looks good (see attached picture).  But I've been debugging and staring at the code for a week and can't get it.  Any suggestions?  Here is the code snippet inside the loop:


 



 



Dim chemPlumePolyFeatureInMemoryLayer As New InMemoryFeatureLayer

chemPlumePolyFeatureInMemoryLayer.Open()


 


'Add a new column to this InMemoryLayer to hold our mainRingID so we'll know which threat we click on later:

chemPlumePolyFeatureInMemoryLayer.Columns.Add(


 


New FeatureSourceColumn(thisChemThreat.mainRingID, "string", 50))'Set the Name to the mainRingID 

chemPlumePolyFeatureInMemoryLayer.Name = thisChemThreat.mainRingID


 


plumePolyShape.Id = currPlume.mapPlumeKey


 


Dim plumePolyShape As New PolygonShape(currPlume.polyPlume.OuterRing)'build feature from the points built from polyPlume

 


 


Dim plumePolyFeature As New Feature(plumePolyShape)'add the plume to the memory layer:

chemPlumePolyFeatureInMemoryLayer.InternalFeatures.Add(currPlume.mapPlumeKey, plumePolyFeature)


 


'set the color

 


If currPlume.polyColor = Color.Transparent Then

 


'outside outline rectangle:

chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.Color =


chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.Width = ringEdgeThickness


 


GeoColor.SimpleColors.BlackElse

 


'main plume: show the plume color (but make semi-transparent)

chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.FillSolidBrush.Color =


chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.OutlinePen.Color =


 


GeoColor.FromArgb(ringOpacity, currPlume.polyColor.R, currPlume.polyColor.G, currPlume.polyColor.B)GeoColor.FromArgb(255, currPlume.polyColor.R, currPlume.polyColor.G, currPlume.polyColor.B)End If

 


'add plume label ("Protective Action Zone")

 


If mnuViewRingLabels.Checked And i = 0 Then

chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle =


chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.GridSize = 1


chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.Font =


chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.PointPlacement =


chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.TextSolidBrush =


chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.Mask =


 


TextStyles.City1(currPlume.labelKey)New GeoFont("Ariel", 10, DrawingFontStyles.Bold)PointPlacement.LowerLeftNew GeoSolidBrush(GeoColor.StandardColors.Blue)AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(200, GeoColor.StandardColors.White), GeoColor.SimpleColors.Black)'add protective action zone label to outer center of transparent polygon

 


Dim pointLatLon As PointF

 


'translate our X/Y points (stored in meters) to Lat/Lon (radians), then to degrees

XY2LatLon(thisChemThreat.centerPosition.Y * DEG2RAD, thisChemThreat.centerPosition.X * DEG2RAD, pointLatLon.X, pointLatLon.Y, currPlume.polyPointsXYRotated(2).X, currPlume.polyPointsXYRotated(2).Y)


 


'convert Lat/Lon (radians) to Lat/Lon (degrees)

pointLatLon.X = pointLatLon.X * RAD2DEG


pointLatLon.Y = pointLatLon.Y * RAD2DEG


 


 


Dim labelLocation As New PointShape(pointLatLon.Y, pointLatLon.X)'set location of label with calculated point - this code here searches for our ringFeature based on its ID to associate with the label:

chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.LabelPositions.Add(currPlume.mapPlumeKey,


 


New WorldLabelingCandidate("Protective Action Zone", labelLocation))End If

 


'make our stuff visible at every zoom level:

chemPlumePolyFeatureInMemoryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel =


ringlayerOverlay.Layers.Add(chemPlumePolyFeatureInMemoryLayer)


ApplyUntilZoomLevel.Level20



OK, so I figured it out afterall…eventhough the polygonShape would draw OK, this turned up an issue that I had drawn it correctly, but needed to add the first point into the shape again to close it out.  All makes sense now, got fooled when the shape would draw OK on the screen.  All set!

Michael,


  I am glad you could figure it out by yourself. Yes, when defining a PolygonShape or a MultiPolygonSape, the last vertex has to be the same as the first so that it is fully closed. We have it that way to abide by the standards set by OGC (Open Geospatial Consortium) en.wikipedia.org/wiki/Well-known_text#Geometric_objects


Thank you.