views:

54

answers:

2

I have a large set of datapoints (all 2D that represent a edges of a shape) where there exists many that all line up in straight lines a series of many points (pixels) I would like to optimize the data by removing the points that make up straight lines (same vector) and leave only the last two end points of the series to define the line and ignore all the points in between (decimation).

Line series that are strictly on X and Y axis of a grid presents one level of complexity. The second level is diagonal lines that when applied to a grid (i.e. pixels) some lines may need to be determined through interpolating a pattern. (i.e. 1 up 3 over, 1 up 4 over, 1 up 5 and so on represents a straight line)

I would like to leverage any existing libraries or example code snippets out there that might already exist instead of reinventing the wheel totally from scratch.

Any pointers, tips, code suggestions, algorithms, partial solutions, etc would be appreciated.

This is going to be a .NET project, but I am well versed in other languages as well (ruby, perl, python) so if such an example exists in similar languages, it would be useful to me.

Thanks

  • Adding link to sample data set: http://pastie.org/1015421
  • Adding a sample image to show the goal of the optimization / decimation

alt text

Updated:

  • We were able to change the incoming data set to be optimized to be a unit-less grid/pixel location based data set from the original source instead of the interpolated unit based locations (to avoid the variances the calculated grid)
  • The example of this input data set (unoptimized) is here http://pastie.org/1017486
  • So far, I've been able to write a routine that will remove the duplicates, and remove any points that have the same x or same y as the previous point
  • Need to find a way to identify reoccurring patterns and eliminate all but the end points of the beginning and end patterns - for straight line decimation.
  • I still haven't found a library, class or code snippet out there where someone has already done this but it seems to me that this is not a new challenge and someone surely has invented this wheel
A: 

There is a really good GIS library called Net Topology Suite that has a lot of geometry type functions. This may cover the functionality you're looking for. It is LGPL licensed. I used it to do polygon intersections with much success.

Garo Yeriazarian
Thanks for the tip on Net Topology Suite. I will investigate it to seem what it can do. I downloaded the zip files, but I can't see to locate any documentation on the website. Are you familiar with any documentation on this library?
Streamline
If you download the "Source" zip, they have sample code in there. I looked at the code, the samples, and the structure of the system to pull what I needed. The code is organized nicely, just doesn't have explicit documentation. There is XML documentation, but you'll have to use Sandcastle to generate a .chm out of it.
Garo Yeriazarian
A: 

what about Douglas Peucker algorithm wikipedia NetTopologySuite has an implemnetation of it i have used it for simplifying GPX tracks

if you convert your data to a LineString then it is dead simple to use

GisSharpBlog.NetTopologySuite.Simplify.DouglasPeuckerLineSimplifier simplifyer = new GisSharpBlog.NetTopologySuite.Simplify.DouglasPeuckerLineSimplifier(lineString.Coordinates);
simplifyer.DistanceTolerance = 5;//some number that makes sense;
GeoAPI.Geometries.ILinearString simplifyedLineString = new GisSharpBlog.NetTopologySuite.Geometries.LineString(simplifyer.Simplify());
LiFo
fossdal, thanks for your input - this looks like something worth trying. in a quick review, however, does your input here: lineString.Coordinates assume the coordinates are all for one line at at time already? How is your lineString created? In my case, it is an array of points ( PointF[] ) that I need to identify the lines in them first and then optimize out what is over definition (simplify). Also, how do get my current data set, PointF[], into the ICoordinate[] class?
Streamline
i assume that the coordinates are ale for one line,it dosent have to be a straight line.you can also use the Static methode on the DouglasPeuckerLineSimplifier.Simplify(coords.ToArray(),Distance);to create the coordinates just loop over your pointF's and create a coords.Add(new GisSharpBlog.NetTopologySuite.Geometries.Coordinate(x, y));i have created a small sample wher you can load the test datayou can download it at http://www.osm.fossdal.dk/SimplifyingSample.zipyou can try it with a value between 0.001 and 0.006
LiFo
fossal, thanks for the sample package. is there any chance you can output it as a VS2008 solution? It appears to be 2010 and I am unable to open it. Thanks! ... I can likely just rebuild it from scratch as well
Streamline
sorry i got no vs2008the code is simple just look at the Form1.cs file
LiFo