ThinkGeo.com    |     Documentation    |     Premium Support

Finding features within other features

Hello,


I need to create shapefile from scratch and also make some queries afterwards and update some features.

Basically, I want to find all features that lie within each other.

I tried to use feature’s IsWithin and Contains method, but it didn’t work. 


Here is my code:



ShapeFileFeatureLayer.CreateShapeFile(ShapeFileType.Polyline, sShapeFileName, pressureDef.Columns, Encoding.Default, OverwriteMode.Overwrite);
            ShapeFileFeatureSource featureSource = new ShapeFileFeatureSource(sShapeFileName, ShapeFileReadWriteMode.ReadWrite);
 
            featureSource.Open();
            featureSource.BeginTransaction();
 
            foreach (PolyLine poly in polyLines)
            {
                if (poly.Type.ToUpper() != "CLOSE"continue;
                Collection<string> col = new Collection<string>();
                col.Add("val:" + poly.Value.ToString("0.#"));
 
                LineShape line = new LineShape();
 
                foreach (PointD point in poly.PointList)
                {
                    line.Vertices.Add(new Vertex(point.X, point.Y));
                }
                Feature f = new Feature(line, col);
                f = f.MakeValid();
                featureSource.AddFeature(f);
            }
            featureSource.CommitTransaction();
 
            List<Feature> group;
            var features = featureSource.GetAllFeatures(ReturningColumnsType.AllColumns);
            foreach (Feature curFeature in features)
            {
                
                group = new List<Feature>();
                group.Add(curFeature);
 
                foreach (Feature f in features)
                {
                    if (f == curFeature) continue;
                    if (curFeature.IsWithin(f))
                    {
                        group.Add(f);
                    }
                }
 
                if (group.Count > 1)
                {
 
                }
            }
            featureSource.Close();

Thanks,

Inna



Hi Inna, 
  
 At first I thought maybe the IsWithin or Contains function have issue, so I did a quickly test as below, my MapSuiteCore.dll is 7.0.0.0 and it looks he function don’t have problem. 
  
 Because I don’t have your PolyLine source data, so please check these items: 
  
 1. Does GetAllFeatures return empty collection? 
 2. If “IsWithIn” keep return false, could you catch the wellknowntext of “curFeature” and “f”, if it looks the points should within but return false, please paste the WKT here so I can help you debug that. 
  
 
            Vertex p1 = new Vertex(0, 0);
            Vertex p2 = new Vertex(1, 1);
            Vertex p3 = new Vertex(3, 5);

            LineShape l1 = new LineShape(new Collection<Vertex> { p1, p2 });
            LineShape l2 = new LineShape(new Collection<Vertex> { p1, p2, p3 });

            Feature f1 = new Feature(l1);
            Feature f2 = new Feature(l2);

            bool r1 = f1.IsWithin(f2);
            bool r2 = f2.Contains(f1);

            Console.WriteLine(r1);
            Console.WriteLine(r2);
            Console.ReadLine();
 
  
 Regards, 
  
 Don

Hi Don,



Attached is a shapefile and a code that fails.



Thanks,

Inna

testshp.txt (3.39 KB)
testshx.txt (116 Bytes)
testdbf.txt (70 Bytes)
TestIsWithinCode.txt (12.1 KB)

Hi Inna,


Thanks for your futher information, the shape is multiline, so the IsWithIn or Contains only works if one shape contains all vertexes of the other.


I render your f1 as red and render f2 as blue.   




It looks they don’t have intersection points, so the result is false.


If you can make sure the MultilineShape is closed, please convert it to any area shape for example polygonshape, then you can adjust their relationship using contains or within.


Regards,


Don



Hi Don,


First of all, in my original application I’m not using MultiLineShapes, only LineShapes. Somehow, shapefile converts them to multilines, I’m not sure why.

Second, not all shapes are closed, so I can’t use Polygon type in a shapefile. 


Maybe you can suggest other way to find inner most closed shapes in a list of lineshapes (or multilineshapes).




Thanks,

Inna  



Hi Inna, 
  
 If shapes aren’t closed, we don’t have a good solution for adjust their spatial relationship. 
  
 Could it be possible temporary “close” all shapes just when adjust? 
  
 It looks you are drawing  something like contour lines, so I think you can close the shapes by connect same value vertex in the four edges. 
  
 Regards, 
  
 Don 


Hi Don, 
  
 Could you please advise what is a proper way to close contour? 
  
 Thanks, 
 Inna 


Hi Inna, 
  
 If your contour don’t contained by an area, please just connect the first vertex and end vertex for make it closed. 
  
 If it contained by any area like your screen capture, I think this function should be works. 
  
   private LineShape CloseContour(LineShape line, RectangleShape rect) 
         { 
             LineShape resultLine = (LineShape)line.CloneDeep(); 
  
             MultipointShape points = line.GetCrossing(rect); 
  
             LineShape outerRingLineShape = new LineShape(rect.ToPolygon().OuterRing.Vertices); 
  
             LineShape newline = (LineShape)outerRingLineShape.GetLineOnALine(points.Points[0], points.Points[1]); 
  
             if (newline.Vertices[0] == line.Vertices[0]) 
             { 
                 for (int i = newline.Vertices.Count - 1; i >= 0; i–) 
                 { 
                     resultLine.Vertices.Add(newline.Vertices); 
                 } 
             } 
             else 
             { 
                 for (int i = 0; i < newline.Vertices.Count; i++) 
                 { 
                     resultLine.Vertices.Add(newline.Vertices); 
                 } 
             } 
  
             return resultLine; 
         } 
  
  
 Regards, 
  
 Don

Thanks. I will check it out.

Inna, 
  
 You’re welcome. 
  
 Any question please let me know. 
  
 Regards, 
  
 Don