简体   繁体   中英

Method to combine adjacent polygons to a single polygon for google maps.

I am new here and new to C#, and am having what I hope is a simple problem to solve.

(I use gmaps.net for winforms for this, but will also use the method via the web API maps version as well).

We have a database of zipcodes and areas in our database. Each area contains multiple zipcodes. Each zipcode has a series of coordinates that create a google maps polygon for that zipcode.

Presently if we want to display our "area" on the map, we do so by drawing the polygons for each of the area's zipcodes without borders and all of the same color (so it appears as one large polygon, just without a border).

Now ive been tasked to add a border to it, but only an outer border - not the borders for each internal zipcode.

Now, I'm not a math genius by any means, but it seems to me there should be a way I can run each group of zipcodes' coordinates (all combined to a single list of PointLatLng), thru a method that will discard all of the "internal" points leaving only the outer border points which we can then use as one single polygon (with border!) for our "Area"... is this possible? CAn someone give me a kick in the right direction for figuring out how to do it?

Thanks!

Jason

Okay, so what you're looking for is a con cave hull instead of a convex hull. Unlike a convex hull, which has only one solution for any given set of points, a concave hull has many solutions and many ways to achieve them. The two most common approaches are alpha shapes or Delauney triangulation , and of the two I'd recommend triangulation.

The short explanation for a Delauney triangulation is the creation of a triangular mesh from a set of points such that the minimum interior angle of any given triangle is as large as possible. There are a lot of existing libraries that can create a Delauney Triangulation for you. (The most highly recommended one seems to be Triangle.NET .)

Once you have a triangulation performed on your set of points, you essentially discard the triangle side information for all sides that are shared between two triangles. This leaves you with only sides that are exclusive to a single triangle, which corresponds to the perimeter of the polygon:

在此处输入图片说明

(Credit to Timothy Shields on this question for the image.)

Once you have this graph of edges, you can simply traverse them (by going from edge to connected node to connected edge and so on) to get an array of points defining your concave hull:

(Pseudocode)

public Point[] GetPolyFromEdgeGraph(Edge[] edges)
{
    List<Point> poly = new List<Point>();

    Edge edge = edges[0];
    Point start = edge.PointA;
    Point point = start;

    do 
    {
        poly.Add(point);

        edge = point.EdgeA != edge ? point.EdgeA : point.EdgeB;
        point = edge.PointA != point ? edge.PointA : edge.PointB;
    } while (point != start);

    return poly.ToArray();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM