[grits] Move polygon parsing into grits-util



commit ab244528448b35dc056427d8fe8d504a82267898
Author: Andy Spencer <andy753421 gmail com>
Date:   Tue Jan 3 07:31:53 2012 +0000

    Move polygon parsing into grits-util
    
    This allows it to be used in other places
    e.g. for line parsing

 src/grits-util.c         |   83 ++++++++++++++++++++++++++++++++++++++++++++++
 src/grits-util.h         |    9 +++++
 src/objects/grits-poly.c |   50 +++------------------------
 3 files changed, 98 insertions(+), 44 deletions(-)
---
diff --git a/src/grits-util.c b/src/grits-util.c
index 8ac6a1b..ab795f9 100644
--- a/src/grits-util.c
+++ b/src/grits-util.c
@@ -70,6 +70,7 @@
 
 #include <glib.h>
 #include <math.h>
+#include <stdio.h>
 
 #include "grits-util.h"
 
@@ -303,3 +304,85 @@ void normd(gdouble *a)
 	a[1] = a[1] / total;
 	a[2] = a[2] / total;
 }
+
+/**
+ * parse_points:
+ * @string:    String representation of the points
+ * @group_sep: Group separator
+ * @point_sep: Point separator
+ * @coord_sep: Coordinate separator
+ * @bounds:    The bounding box of all the points, or NULL
+ * @center:    The center of the @bounds, or NULL
+ *
+ * Parse a string of the form:
+ *   string -> group [ group_sep group] ...
+ *   group  -> point [ point_sep point] ...
+ *   point  -> latitude @coord_sep longitude [ coord_sep elevation]
+ *
+ * For example
+ *   parse_points("30,-80 30,-120 50,-120 50,-80", "\t", " ", ",");
+ *
+ * Returns: zero-terminated array of groups of points
+ */
+GritsPoints *parse_points(const gchar *string,
+		const gchar *group_sep, const gchar *point_sep, const gchar *coord_sep,
+		GritsBounds *bounds, GritsPoint *center)
+{
+	/* Split and count groups */
+	gchar **sgroups = g_strsplit(string, group_sep, -1);
+	int     ngroups = g_strv_length(sgroups);
+
+	GritsBounds _bounds = {-90, 90, -180, 180};
+	gdouble (**groups)[3] = (gpointer)g_new0(double*, ngroups+1);
+	for (int pi = 0; pi < ngroups; pi++) {
+		/* Split and count coordinates */
+		gchar **scoords = g_strsplit(sgroups[pi], point_sep, -1);
+		int     ncoords = g_strv_length(scoords);
+
+		/* Create binary coords */
+		gdouble (*coords)[3] = (gpointer)g_new0(gdouble, 3*(ncoords+1));
+		for (int ci = 0; ci < ncoords; ci++) {
+			gdouble lat, lon;
+			sscanf(scoords[ci], "%lf,%lf", &lat, &lon);
+			if (bounds || center) {
+				if (lat > _bounds.n) _bounds.n = lat;
+				if (lat < _bounds.s) _bounds.s = lat;
+				if (lon > _bounds.e) _bounds.e = lon;
+				if (lon < _bounds.w) _bounds.w = lon;
+			}
+			lle2xyz(lat, lon, 0,
+					&coords[ci][0],
+					&coords[ci][1],
+					&coords[ci][2]);
+		}
+
+		/* Insert coords into line array */
+		groups[pi] = coords;
+		g_strfreev(scoords);
+	}
+	g_strfreev(sgroups);
+
+	/* Output */
+	if (bounds)
+		*bounds = _bounds;
+	if (center) {
+		center->lat  = (_bounds.n + _bounds.s)/2;
+		center->lon  = lon_avg(_bounds.e, _bounds.w);
+		center->elev = 0;
+	}
+	return groups;
+}
+
+/**
+ * free_points:
+ * @points: Array of points allocated by parse_points()
+ *
+ * Frees all data allocated by parse_points
+ */
+void free_points(GritsPoints *points)
+{
+	gdouble (**_points)[3] = points;
+	for (int i = 0; _points[i]; i++)
+		g_free(_points[i]);
+	g_free(_points);
+}
diff --git a/src/grits-util.h b/src/grits-util.h
index ccfff16..0fa144d 100644
--- a/src/grits-util.h
+++ b/src/grits-util.h
@@ -159,6 +159,9 @@ struct _GritsPoint {
 void grits_point_set_lle(GritsPoint *point,
 		gdouble lat, gdouble lon, gdouble elev);
 
+/* GritsPoints */
+typedef gdouble (*GritsPoints)[3];
+
 /* GritsBounds */
 typedef struct _GritsBounds GritsBounds;
 struct _GritsBounds {
@@ -212,4 +215,10 @@ void normd(gdouble *a);
 
 gdouble lon_avg(gdouble a, gdouble b);
 
+GritsPoints *parse_points(const gchar *string,
+		const gchar *group_sep, const gchar *point_sep, const gchar *coord_sep,
+		GritsBounds *bounds, GritsPoint *center);
+
+void free_points(GritsPoints *points);
+
 #endif
diff --git a/src/objects/grits-poly.c b/src/objects/grits-poly.c
index 25a81b5..c2c9923 100644
--- a/src/objects/grits-poly.c
+++ b/src/objects/grits-poly.c
@@ -173,55 +173,17 @@ GritsPoly *grits_poly_new(gdouble (**points)[3])
 	return poly;
 }
 
-static void _free_points(gdouble (**points)[3])
-{
-	for (int i = 0; points[i]; i++)
-		g_free(points[i]);
-	g_free(points);
-}
-
 GritsPoly *grits_poly_parse(const gchar *str,
 		const gchar *poly_sep, const gchar *point_sep, const gchar *coord_sep)
 {
-	/* Split and count polygons */
-	gchar **spolys = g_strsplit(str, poly_sep, -1);
-	int     npolys = g_strv_length(spolys);
-
-	GritsBounds bounds = {-90, 90, -180, 180};
-	gdouble (**polys)[3] = (gpointer)g_new0(double*, npolys+1);
-	for (int pi = 0; pi < npolys; pi++) {
-		/* Split and count coordinates */
-		gchar **scoords = g_strsplit(spolys[pi], point_sep, -1);
-		int     ncoords = g_strv_length(scoords);
-
-		/* Create binary coords */
-		gdouble (*coords)[3] = (gpointer)g_new0(gdouble, 3*(ncoords+1));
-		for (int ci = 0; ci < ncoords; ci++) {
-			gdouble lat, lon;
-			sscanf(scoords[ci], "%lf,%lf", &lat, &lon);
-			if (lat > bounds.n) bounds.n = lat;
-			if (lat < bounds.s) bounds.s = lat;
-			if (lon > bounds.e) bounds.e = lon;
-			if (lon < bounds.w) bounds.w = lon;
-			lle2xyz(lat, lon, 0,
-					&coords[ci][0],
-					&coords[ci][1],
-					&coords[ci][2]);
-		}
-
-		/* Insert coords into poly array */
-		polys[pi] = coords;
-		g_strfreev(scoords);
-	}
-	g_strfreev(spolys);
+	GritsPoint center;
+	gdouble (**polys)[3] = parse_points(str,
+			poly_sep, point_sep, coord_sep, NULL, &center);
 
-	/* Create GritsPoly */
 	GritsPoly *poly = grits_poly_new(polys);
-	GRITS_OBJECT(poly)->center.lat  = (bounds.n + bounds.s)/2;
-	GRITS_OBJECT(poly)->center.lon  = lon_avg(bounds.e, bounds.w);
-	GRITS_OBJECT(poly)->center.elev = 0;
-	GRITS_OBJECT(poly)->skip        = GRITS_SKIP_CENTER;
-	g_object_weak_ref(G_OBJECT(poly), (GWeakNotify)_free_points, polys);
+	GRITS_OBJECT(poly)->center = center;
+	GRITS_OBJECT(poly)->skip   = GRITS_SKIP_CENTER;
+	g_object_weak_ref(G_OBJECT(poly), (GWeakNotify)free_points, polys);
 	return poly;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]