ThinkGeo.com    |     Documentation    |     Premium Support

How to construct MultipolygonShape instance with several Polygons drawn

In order to use attributes of MultipolygonShape to save polygons vertices, it is necessary to instantiate a MultipolygonShape with several Polygons stored in FeatureLayer, POLYGON, by InMemoryFeatureLayer internal feature add method at Track_End event handler. However, the Polygons thus saved belong to PolygonShape which cannot be casted into MultipolygonShape.

What will be the syntax to build the MultipolygonShape constructor for the purpose of accessing these inmemory Polygons' vertices via the instance? Please take a look at the code attached and advise me how to tackle the problem.Thanks


 


 



ExampleCode.txt (1.68 KB)

Hi Franklin, 
  
 The code you pasted is missing some brackets, we suppose what you want to do is to transfer several PolygonShapes into one MultiPolygonShape. Please let us know if we guessed wrong. 
 If we guessed right, then here is how to accomplish that: 
 MultipolygonShape has a constructor that takes multiple polygons, it’s defined like this: 
 public MultipolygonShape(IEnumerable<PolygonShape> polygons); 
 You can pass your polygon shapes into it and you’ll get an instance of MultipolygonShape that contains all the vertices. 
  
 Please let us know if you have any other questions. 
  
 Regards, 
 Tsui

and here is some code that may be of help: 



<polygonshape>
<polygonshape>

IEnumerable<PolygonShape> allPolygons = inMemoryFeatureLayer.FeatureSource
                                                            .GetAllFeatures(ReturningColumnsType.AllColumns)
                                                            .OfType<PolygonShape>();
MultipolygonShape multipolygonShape = new MultipolygonShape(allPolygons);





Regards,  

Tsui</polygonshape>
</polygonshape>



Hi Tsui, 
  
   When typing in "inMemoryFeatureLayer.FeatureSource" in VS2010, the "FeatureSource" is not allowed and underlined in red. 
 I am using WpfDesktop 4.5 in the application, which version of WpfDesktop is allowed to enter inMemoryFeatureLayer.FeatureSource? 
 Thanks. 
  
 Regards, 
 Franklin

Tsui, 
  
 I guess the "inMemoryFeatuerLayer" above is actually the FeatureLayer created under "PolyLayer". If I do the replacement, then the "FeatureSource" problem is resolved. Am I understanding you correctly? 
 Thanks for the hint. 
  
 Regards, 
 Franklin

Hi Frankin, 
  
 Sorry for the confusion, the code I pasted was not based on your code. 
 But you understood it correctly. And I guess you can get multi-polygon shape out of polygon shapes now, right? 
  
 Please let us know if you have any other questions. 
  
 Regards,  
 Tsui

Tsui, 



The modified method is as shown in the attachement below.



The featurelayer generation method was shown in previous post attachment. I drew 1 polygon in the map, then clicked the save button which leads to the runtime problem.

What could be wrong? Thanks. 



Regards, 

Franklin 



 



modifiedMethod.txt (663 Bytes)

Hi Franklin, 
  
 The code you attached has some format issues, there are some brackets missing. 
 But we guess the problem is that you are traversing the collection using zero as the index every time, and there are no items in the collection, which means the polygLayer parameter doesn’t contain any polygon shapes. 
  
 Hope you can send us a sample that demonstrates the problem the next time, so we can figure out the problem easier. 
  
 Regards, 
 Tsui

Tsui, 
  
   It seems that the MultipolygonShape instance doesn’t have any polygon at all. Could you check ExampleCode.txt above to see if anything is wrong with 
 the TrackOverlay_TrackEnded handler? Thanks.  There must be something wrong in that method.  Do you know how to get IEnumerable PolygonShape from 
 wpfMap.TrackOverlay.TrackShapeLayer?  
  
 Regards, 
  
 Franklin

 Hi Franklin, 


We made a sample that you can draw polygons on the track overlay, then you can click a button let it show you how many polygons are there and how many vertices are there in the polygons.


It looks like this:


 


The code to get polygons out of track overlay and to get vertices out of multipolygon is like this:


 
        private void Button_Click(object sender, RoutedEventArgs e)

        {

            map.TrackOverlay.TrackShapeLayer.Open();

 

            var allFeaturesInTrackOverlay = map.TrackOverlay.TrackShapeLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.NoColumns);

            var allPolygonShapes = allFeaturesInTrackOverlay.Select(feature => feature.GetShape()).OfType<PolygonShape>();

 

            MultipolygonShape multiPolygonShape = new MultipolygonShape(allPolygonShapes);

            var allVerticesInOuterRing = multiPolygonShape.Polygons.SelectMany(polygonShape => polygonShape.OuterRing.Vertices);

 

            MessageBox.Show(string.Format("There are {0} polygons in multipolygon and there are {1} vertices in multipolygon", multiPolygonShape.Polygons.Count, allVerticesInOuterRing.Count()));

        }


Hope this will help. 


Regards,


Tsui



Hi Tsui, 



The MultiPolygonShape instance is well constructed, thanks very much. In executing " Vertex vtx=proj4.ConvertToInternalProjection(vtxs[j].X,vtxs[j].Y);" 

encountered "Projection is not open...". May I know the sequence of things to be done for opening a projection? Thanks a lot.



Regards, 



Franklin



Hi Franklin, 
  
 In this case, you just need to open the projection before you use it to do any conversion and make sure its internal parameters and external parameters are set properly, and then you are in good shape. 
  
 Please let us know if you have any other questions. 
  
 Regards, 
 Tsui

Hi Tsui, 
  
    proj4 is declared as " private Proj4Projection proj4= new Proj4Projection() ",  
 I cannot simply do "proj4.Open()"  before the above vtx computation as it gives me a runtime error. 
 Are you implying to open the projection of the TrackShapeLayer? 
 I do not understand the concepts behind it. Could you please shed more light? Thanks a lot. 
  
 Regards, 
 Franklin  


 Hi Franklin,


 
Let’s assume we want to convert a point from EPSG: 4326 to EPSG: 2163, and the point is located in [15, 15]. Here is how to do that:
//this is the point we need to convert
Vertex originalVertex = new Vertex(15, 15);

//create a project and pass in the internal and external parameters
Proj4Projection projection = new Proj4Projection(4326, 2163);
//open the projection
projection.Open();
//convert the point to EPSG:2163(which is the external parameter we passed in)
Vertex convertedVertex = projection.ConvertToExternalProjection(originalVertex.X, originalVertex.Y);
//show the conversion result
MessageBox.Show(string.Format("{0} {1}", convertedVertex.X, convertedVertex.Y));

 
Hope this will help.
 
Regards,
Tsui

Hi Tsui, 
  
   The example is very interesting. My intention is to capture the vertices stored in TrackShapeLayer(in 4326? Singapore map?) and convert them into Latitude and Longitude.I am not sure what would be the appropriate internal and external parameter setting for my case. For "ConvertToInternalProjection", would you reverse the parameter setting as: Proj4Projection projection = new Proj4Projection(2163,4326) ? 
 I really appreciate your enlightening. Thanks. 
  
 Regards, 
  
 Franklin 


Hi Franklin, 
  
 The vertices stored in the track overlay are in Lat/Long format by default, there is no need to convert them. 
  
 Hope this will help. 
  
 Regards, 
 Tsui

Hi Tsui, 
  
     Problem solved. I solute to your great professionalism, you are great! Thanks very much. 
  
 Regards, 
  
 Franklin

Hi Franklin, 
  
 You are welcome, I am glad to be of help. 
 Please let us know if you have any other questions. 
  
 Regards, 
 Tsui

Hi Tsui, 
  
    One more question on this topic. Suppose that there is another button "Track Edit" in your polygon example above. After drawing the polygones, I click the  
 "Track & Edit" button and pick up one (or two)  of the polygons to edit. After editing, I click the save button. Then the present method will not produce a multiPolygonShape instance to reflect the edit effects. I try to modify the original method. as follows: 
 if (wpfMap1.TrackOverlay.TrackMode== TrackMode.None) 
 { 
    … 
 } 
 The trouble is that  in wpfMap1.EditOverlay.EditShapesLayer,  difficult to find the corresponding methods for constructing  var allfeaturesInEditOverlay  
 and var allPolygonShapes. Can you show me how to do this variation due to the edit mode? 
 Can I assume that once the if condition is satisfied, the EditShapeLayer is already open? 
 Thanks very much. 
  


 Hi Franklin,


 


Finding all polygons in edit overlay and convert them into one multipolygon is basically the same thing with doing it in track overlay.


The following code shows how to do it:


 if (!Map1.EditOverlay.EditShapesLayer.IsOpen)
{
    Map1.EditOverlay.EditShapesLayer.Open();
}

var allFeaturesInEditOverlay = Map1.EditOverlay.EditShapesLayer.FeatureSource
                                                               .GetAllFeatures(ReturningColumnsType.NoColumns);

var allPolygonShapes = allFeaturesInEditOverlay
                       .Select(feature => feature.GetShape())
                       .OfType<PolygonShape>();

MultipolygonShape multiPolygonShape = new MultipolygonShape(allPolygonShapes);

var allVerticesInOuterRing = multiPolygonShape.Polygons
                                              .SelectMany(polygonShape => polygonShape.OuterRing.Vertices);

MessageBox.Show(string.Format("There are {0} polygons in the Edited Result and there are {1} vertices in the Edited Result", multiPolygonShape.Polygons.Count, allVerticesInOuterRing.Count()));


For the second question, we’d suggest you to make sure the EditShapesLayer is open before doing any operation to it. And the easiest way to do that is like this:


 if (!Map1.EditOverlay.EditShapesLayer.IsOpen)
{
    Map1.EditOverlay.EditShapesLayer.Open();
}


Hope this would be of help.


 


Regards,


Tsui