ThinkGeo.com    |     Documentation    |     Premium Support

Line Shape and Polygons

Hi Guys,



I have a line shape and one multipolygon (contains two polygons or more) I want to have a function to be able to check if the two polygons are covering the whole of line shape or not.



For example: See image 1: the function should return false







Image 2: the function should return true









Appreciate your advise on how I can achieve this function.


Hi Mostafa, 
  
 I think our API cannot implement that easily. 
  
 The solution is you can create a function follow this thinking. 
  
 1. Loop all polygons, get intersection vertex between line and each polygon, add them to one collection 
 2. Add ending vertex to this collection also 
 3. select any one ending vertex as start point, sort this collection 
 4. From start point, we think we save many segments in collection now(vertex 1 to vertex 2 meant segment 1, vertex 2 to vertex 3 meant segment 2, etc.) 
 5. Loop the segments and get center point of them, loop all polygons, see whether anyone contains the center point. 
 6. Any segment center point aren’t contained by all the polygons, the final result is false, all segment center point are contained by any polygon, final result is true. 
  
 I think that will works, any question please let me know. 
  
 Regards, 
  
 Don

Thanks Don for your reply. 
  
 Would you please provide me a sample code that I can work/extend on?

If I were doing it, I would use the simple statement:     



        bool isContained = multiPolygon.Contains(line);



This will return true if the line (or multi-line) is contained entirely within the multi-polygon.    You can use the .Overlaps method if you want to know if any part of the line is contained within the multi-polygon.



And, by the way… your Figure 2 is an invalid geometry.   I’m not sure if ThinkGeo supports it or not.    You cannot have a multi-polygon with overlapping exterior rings.


Hi Ted, 
  
 I am sorry we don’t have a sample for that, but if you met any problem when you implement that please feel free to ask me, I can help you on it. 
  
 And the “bool isContained = multiPolygon.Contains(line);” shouldn’t works well follow your requirement, the inner logic for it is loop all polygons in the multiPolygon and anyone of them contains the line, it return true. So I don’t think it can give you a correct result and provide you the thinking as workaround. 
  
 I don’t think the Figure 2 is invalid, have you met the exception when you create it? 
  
 Regards, 
  
 Don

I am not the one trying to accomplish this.   I was trying to provide a much simpler solution to Mostafa. 
  
 The definition of Contains, within GIS is that an entire geometry lies within another geometry.   Figure 1 would fail because part of the line lies outside of both rings.   Figure 2 would test true because the entire line lies within either the first or the second ring.   Now, maybe you didn’t implement Contains, correctly, but in the NTS and SQL Server implementation (which I believe you use), the Contains IS implemented correctly so the single statement would work. 
  
 And, if you generate a WKT for that Figure 2 MultiPolygon, and you load it into an NTS or SQLServer geometry object, and call MakeValid(), the overlapping area will be combined such that you end up with a single polygon, rather than two overlapping polygons. 
  


Hi Ted, 
  
 I think our MultiPolygon is not totally the same as the one in NTS, because it looks we need to split the polygons to separate ones when necessary. 
  
 Today I tried to use our NTS engine to implement the contains, but get an exception “side location conflict [ (5, 10, NaN) ]”, I am not sure that why our developer haven’t directly implement that by NTS. 
  
 My test data as below: 
  
  MultipolygonShape mps = new MultipolygonShape(); 
             RectangleShape rect1 = new RectangleShape(0, 10, 10, 0); 
             RectangleShape rect2 = new RectangleShape(5, 15, 15, 5); 
  
             mps.Polygons.Add(rect1.ToPolygon()); 
             mps.Polygons.Add(rect2.ToPolygon()); 
  
             LineShape line = new LineShape(); 
             line.Vertices.Add(new Vertex(1, 1)); 
             line.Vertices.Add(new Vertex(14, 14)); 
  
             bool result =  mps.Contains(line); 
  
  
 So I think my original workaround thinking should can get correct result, but if you need to get a simpler solution and there is any way or library is helpful for that, please override ContainsCore in MultipolygonShape and that will works. 
  
 I will let our developer knows the contains don’t works well now and see whether we can enhancement it. 
  
 Regards, 
  
 Don

Hi Guys,



Thanks all for your feedback, I sort of accomplished what I needed but I ran into different and various cases now during my implementation.



What was needed is that I have a line shape and multi polygons covering the whole line, some polygons are covering the same areas covered by other polygons. So i need to ignore the shapes covering the same area on the line. i.e. one point on the line should be only covered by one shape.



So what I did is, i take each shape and get the crossing points on the line, then I make sure that these two points are not covered by any other shape.



However, I ran into this scenario and I’m running out of ideas to solve it… see this figure below





In this figure, each shape is a polygon by it self, so I need to select Shape B and NOT Shape A (because shape B is covering most area on the line than Shape A) However, since I was relying on the Crossing points, both shapes have one crossing points on the line.



Any thoughts will be much appreciated…



Thanks


I would do an intersection of the line with A (which will yield a line) and then B, and check the .Length property of the result.  The one that is the longest is the polygon that you want.

Hi Mostafa,  
  
 I think Ted’s solution is the best one, I cannot find a simpler solution for your requirement here.  
  
 Regards, 
  
 Don

Hi Ted and Don, 



Thanks for your tips, I think after spending too much time on it minds got frozen for a bit but then I ended up with two solutions now. 



- By length of line as you have suggested, Ted. Much appreciated. 



- By Crossing Point on line, so get Shape A crossing point and see is any other shape .Contains the point, if found, then we get the crossing point of the other shape, and then if the the crossing point .Contains previous shape then we dont need previous shape which is Shape A. So we end up with Shape B only. 



Many thanks again for your thoughts and tips…

Hi Mostafa, 
  
 Thanks for your update, and thanks for Ted’s help on this topic. 
  
 Regards, 
  
 Don