From 2d9c78a57c669ecac2a03f5c0019e538b1697340 Mon Sep 17 00:00:00 2001
From: Andrea Zagli <azagli@libero.it>
Date: Tue, 11 Aug 2009 22:05:47 +0200
Subject: [PATCH] Initial implementation of layer's label

---
 data/gtkgis.dtd                           |  9 ++-
 docs/reference/libgtkgis-decl-list.txt    |  4 +
 docs/reference/libgtkgis-decl.txt         | 24 +++++-
 docs/reference/libgtkgis-undocumented.txt |  8 +-
 docs/reference/libgtkgis-unused.txt       |  4 +
 docs/reference/tmpl/layer.sgml            |  1 +
 docs/reference/tmpl/layersource.sgml      |  1 +
 src/commons.h                             |  8 ++
 src/geometry.c                            | 45 +++++++++++-
 src/geometry.h                            |  3 +
 src/layer.c                               | 90 ++++++++++++++++++++++-
 src/layer.h                               |  5 +-
 src/layersource.c                         | 25 ++++++-
 src/layersource.h                         |  3 +-
 14 files changed, 213 insertions(+), 17 deletions(-)

diff --git a/data/gtkgis.dtd b/data/gtkgis.dtd
index b7d8922..f104b00 100644
--- a/data/gtkgis.dtd
+++ b/data/gtkgis.dtd
@@ -2,7 +2,7 @@
 
 <!ELEMENT group (layer*)>
 
-<!ELEMENT layer (source, style?)>
+<!ELEMENT layer (source, style?, label?)>
 <!ATTLIST layer
 	name CDATA #REQUIRED
 	visible (y | n) "y"
@@ -33,3 +33,10 @@
 <!ELEMENT width (#PCDATA)>
 <!ELEMENT stroke-color (#PCDATA)>
 <!ELEMENT fill-color (#PCDATA)>
+
+<!ELEMENT label (field, color?, background-color?, font?)>
+
+<!ELEMENT field (#PCDATA) />
+<!ELEMENT color (#PCDATA) />
+<!ELEMENT background-color (#PCDATA) />
+<!ELEMENT font (#PCDATA) />
diff --git a/docs/reference/libgtkgis-decl-list.txt b/docs/reference/libgtkgis-decl-list.txt
index 4297a60..9e39428 100644
--- a/docs/reference/libgtkgis-decl-list.txt
+++ b/docs/reference/libgtkgis-decl-list.txt
@@ -126,6 +126,8 @@ gtk_gis_layer_get_editable
 gtk_gis_layer_set_editable
 gtk_gis_layer_get_style
 gtk_gis_layer_set_style
+gtk_gis_layer_get_label
+gtk_gis_layer_set_label
 gtk_gis_layer_draw
 </SECTION>
 
@@ -164,6 +166,8 @@ GtkGisGeometry
 gtk_gis_geometry_get_type
 gtk_gis_geometry_get_editable
 gtk_gis_geometry_set_editable
+gtk_gis_geometry_get_label
+gtk_gis_geometry_set_label
 gtk_gis_geometry_draw
 </SECTION>
 
diff --git a/docs/reference/libgtkgis-decl.txt b/docs/reference/libgtkgis-decl.txt
index 099171a..b725a23 100644
--- a/docs/reference/libgtkgis-decl.txt
+++ b/docs/reference/libgtkgis-decl.txt
@@ -500,7 +500,7 @@ GtkGisLayer *layer
 <FUNCTION>
 <NAME>gtk_gis_layer_fill_from_source</NAME>
 <RETURNS>void </RETURNS>
-GtkGisLayer *layer
+GtkGisLayer *layer, GtkGisLayerLabel *label
 </FUNCTION>
 <FUNCTION>
 <NAME>gtk_gis_layer_save</NAME>
@@ -553,6 +553,16 @@ GtkGisLayer *layer
 GtkGisLayer *layer, GtkGisLayerStyle style
 </FUNCTION>
 <FUNCTION>
+<NAME>gtk_gis_layer_get_label</NAME>
+<RETURNS>GtkGisLayerLabel *</RETURNS>
+GtkGisLayer *layer
+</FUNCTION>
+<FUNCTION>
+<NAME>gtk_gis_layer_set_label</NAME>
+<RETURNS>void </RETURNS>
+GtkGisLayer *layer, GtkGisLayerLabel *label
+</FUNCTION>
+<FUNCTION>
 <NAME>gtk_gis_layer_draw</NAME>
 <RETURNS>void </RETURNS>
 GtkGisLayer *layer, GooCanvasItem *root, GtkGisScale *scale
@@ -695,6 +705,16 @@ GtkGisGeometry *geometry
 GtkGisGeometry *geometry, gboolean editable
 </FUNCTION>
 <FUNCTION>
+<NAME>gtk_gis_geometry_get_label</NAME>
+<RETURNS>const gchar *</RETURNS>
+GtkGisGeometry *geometry
+</FUNCTION>
+<FUNCTION>
+<NAME>gtk_gis_geometry_set_label</NAME>
+<RETURNS>void </RETURNS>
+GtkGisGeometry *geometry, const gchar *label
+</FUNCTION>
+<FUNCTION>
 <NAME>gtk_gis_geometry_draw</NAME>
 <RETURNS>GooCanvasItem *</RETURNS>
 GtkGisGeometry *geometry,GtkGisScale *scale,GtkGisLayerStyle style
@@ -886,7 +906,7 @@ GtkGisLayerSource *source
 <FUNCTION>
 <NAME>gtk_gis_layer_source_get_geometries</NAME>
 <RETURNS>GSList *</RETURNS>
-GtkGisLayerSource *source,const gchar *name
+GtkGisLayerSource *source,const gchar *name,const gchar *label_fieldname
 </FUNCTION>
 <FUNCTION>
 <NAME>gtk_gis_layer_source_get_layer_geometry_type</NAME>
diff --git a/docs/reference/libgtkgis-undocumented.txt b/docs/reference/libgtkgis-undocumented.txt
index 9e381ac..fedae38 100644
--- a/docs/reference/libgtkgis-undocumented.txt
+++ b/docs/reference/libgtkgis-undocumented.txt
@@ -1,7 +1,7 @@
 11% symbol docs coverage.
 22 symbols documented.
 7 symbols incomplete.
-175 not documented.
+179 not documented.
 
 
 GTK_GIS
@@ -94,6 +94,7 @@ gtk_gis_add_layer
 gtk_gis_draw
 gtk_gis_geometry_draw
 gtk_gis_geometry_get_editable
+gtk_gis_geometry_get_label
 gtk_gis_geometry_get_point
 gtk_gis_geometry_get_type
 gtk_gis_geometry_line_add_point
@@ -110,6 +111,7 @@ gtk_gis_geometry_polygon_remove_line
 gtk_gis_geometry_raster_get_type
 gtk_gis_geometry_raster_new_from_pixbuf (x, y, width, height, x, y, width, height)
 gtk_gis_geometry_set_editable
+gtk_gis_geometry_set_label
 gtk_gis_get_layer_by_name
 gtk_gis_get_legend
 gtk_gis_get_scale
@@ -119,6 +121,7 @@ gtk_gis_layer_add_geometry
 gtk_gis_layer_draw
 gtk_gis_layer_get_editable
 gtk_gis_layer_get_extent
+gtk_gis_layer_get_label
 gtk_gis_layer_get_name
 gtk_gis_layer_get_source
 gtk_gis_layer_get_style
@@ -128,8 +131,9 @@ gtk_gis_layer_get_xml
 gtk_gis_layer_new (geometrytype, geometry_type)
 gtk_gis_layer_remove_geometry
 gtk_gis_layer_set_editable
+gtk_gis_layer_set_label
 gtk_gis_layer_set_visible
-gtk_gis_layer_source_get_geometries (name, name)
+gtk_gis_layer_source_get_geometries (name, name, label_fieldname)
 gtk_gis_layer_source_get_layer_extent
 gtk_gis_layer_source_get_layer_geometry_type
 gtk_gis_layer_source_get_type
diff --git a/docs/reference/libgtkgis-unused.txt b/docs/reference/libgtkgis-unused.txt
index 65ad8c0..789dcc8 100644
--- a/docs/reference/libgtkgis-unused.txt
+++ b/docs/reference/libgtkgis-unused.txt
@@ -10,9 +10,13 @@ GtkGisLayerSourcePostgisClass
 GtkGisLayerSourceRasterClass
 GtkGisLayerSourceShpClass
 GtkGisLayersGroupClass
+gtk_gis_geometry_get_label
 gtk_gis_geometry_line_get_svg_path
+gtk_gis_geometry_set_label
+gtk_gis_layer_get_label
 gtk_gis_layer_get_style
 gtk_gis_layer_get_visible
+gtk_gis_layer_set_label
 gtk_gis_layer_set_style
 gtk_gis_layer_set_visible
 gtk_gis_move_to
diff --git a/docs/reference/tmpl/layer.sgml b/docs/reference/tmpl/layer.sgml
index 41029a7..95f4c19 100644
--- a/docs/reference/tmpl/layer.sgml
+++ b/docs/reference/tmpl/layer.sgml
@@ -132,6 +132,7 @@ GtkGisLayer
 </para>
 
 @layer: 
+@label: 
 
 
 <!-- ##### FUNCTION gtk_gis_layer_save ##### -->
diff --git a/docs/reference/tmpl/layersource.sgml b/docs/reference/tmpl/layersource.sgml
index cf3b90a..b1c44cf 100644
--- a/docs/reference/tmpl/layersource.sgml
+++ b/docs/reference/tmpl/layersource.sgml
@@ -94,6 +94,7 @@ GtkGisLayerSource
 
 @source: 
 @name: 
+@label_fieldname: 
 @Returns: 
 
 
diff --git a/src/commons.h b/src/commons.h
index e71b9c6..2875222 100644
--- a/src/commons.h
+++ b/src/commons.h
@@ -54,6 +54,14 @@ typedef struct
 		gchar *fill_color;
 	} GtkGisLayerStyle;
 
+typedef struct
+	{
+		gchar *field;
+		gchar *color;
+		gchar *background_color;
+		gchar *font;
+	} GtkGisLayerLabel;
+
 typedef enum
 	{
 		LAYER_GEOMETRY_TYPE_UNKNOWN,
diff --git a/src/geometry.c b/src/geometry.c
index ec07da4..d2a98c6 100644
--- a/src/geometry.c
+++ b/src/geometry.c
@@ -47,6 +47,8 @@ typedef struct _GtkGisGeometryPrivate GtkGisGeometryPrivate;
 struct _GtkGisGeometryPrivate
 	{
 		gboolean editable;
+
+		gchar *label;
 	};
 
 G_DEFINE_TYPE (GtkGisGeometry, gtk_gis_geometry, G_TYPE_OBJECT)
@@ -78,7 +80,11 @@ gtk_gis_geometry_init (GtkGisGeometry *gtk_gis_geometry)
 gboolean
 gtk_gis_geometry_get_editable (GtkGisGeometry *geometry)
 {
-	GtkGisGeometryPrivate *priv = GTK_GIS_GEOMETRY_GET_PRIVATE (geometry);
+	GtkGisGeometryPrivate *priv;
+
+	g_return_val_if_fail (IS_GTK_GIS_GEOMETRY (geometry), FALSE);
+
+	priv = GTK_GIS_GEOMETRY_GET_PRIVATE (geometry);
 
 	return priv->editable;
 }
@@ -92,11 +98,46 @@ gtk_gis_geometry_get_editable (GtkGisGeometry *geometry)
 void
 gtk_gis_geometry_set_editable (GtkGisGeometry *geometry, gboolean editable)
 {
-	GtkGisGeometryPrivate *priv = GTK_GIS_GEOMETRY_GET_PRIVATE (geometry);
+	GtkGisGeometryPrivate *priv;
+
+	g_return_if_fail (IS_GTK_GIS_GEOMETRY (geometry));
+
+	priv = GTK_GIS_GEOMETRY_GET_PRIVATE (geometry);
 
 	priv->editable = editable;
 }
 
+/**
+ * gtk_gis_geometry_get_label:
+ * @geometry:
+ *
+ */
+const gchar
+*gtk_gis_geometry_get_label (GtkGisGeometry *geometry)
+{
+	GtkGisGeometryPrivate *priv;
+	
+	g_return_val_if_fail (IS_GTK_GIS_GEOMETRY (geometry), NULL);
+
+	return g_strdup (priv->label);
+}
+
+/**
+ * gtk_gis_geometry_set_label:
+ * @geometry:
+ * @label:
+ *
+ */
+void
+gtk_gis_geometry_set_label (GtkGisGeometry *geometry, const gchar *label)
+{
+	GtkGisGeometryPrivate *priv;
+	
+	g_return_if_fail (IS_GTK_GIS_GEOMETRY (geometry));
+
+	priv->label = g_strdup (label);
+}
+
 /**
  * gtk_gis_geometry_draw:
  * @geometry: a #GtkGisGeometry object.
diff --git a/src/geometry.h b/src/geometry.h
index 8fbf675..d1f1af2 100644
--- a/src/geometry.h
+++ b/src/geometry.h
@@ -61,6 +61,9 @@ GType gtk_gis_geometry_get_type (void) G_GNUC_CONST;
 gboolean gtk_gis_geometry_get_editable (GtkGisGeometry *geometry);
 void gtk_gis_geometry_set_editable (GtkGisGeometry *geometry, gboolean editable);
 
+const gchar *gtk_gis_geometry_get_label (GtkGisGeometry *geometry);
+void gtk_gis_geometry_set_label (GtkGisGeometry *geometry, const gchar *label);
+
 GooCanvasItem *gtk_gis_geometry_draw (GtkGisGeometry *geometry,
                                       GtkGisScale *scale,
                                       GtkGisLayerStyle style);
diff --git a/src/layer.c b/src/layer.c
index c0d40f5..b6628d7 100644
--- a/src/layer.c
+++ b/src/layer.c
@@ -58,6 +58,8 @@ struct _GtkGisLayerPrivate
 		gboolean editable;
 
 		GtkGisLayerStyle *style;
+
+		GtkGisLayerLabel *label;
 	};
 
 G_DEFINE_TYPE (GtkGisLayer, gtk_gis_layer, G_TYPE_OBJECT)
@@ -85,6 +87,8 @@ gtk_gis_layer_init (GtkGisLayer *gtk_gis_layer)
 	priv->style->width = 0.5;
 	priv->style->stroke_color = g_strdup ("black");
 	priv->style->fill_color =  g_strdup ("white");
+
+	priv->label = NULL;
 }
 
 /**
@@ -166,6 +170,11 @@ xmlNode
 			xmlSetProp (xnode, "name", priv->name);
 		}
 
+	if (!priv->visible)
+		{
+			xmlSetProp (xnode, "visible", "n");
+		}
+
 	if (priv->source != NULL)
 		{
 			xmlNode *xnode_source;
@@ -174,6 +183,40 @@ xmlNode
 			xmlAddChild (xnode, xnode_source);
 		}
 
+	if (priv->style != NULL)
+		{
+			xmlNode *xnode_style;
+			xmlNode *xnode_style_prop;
+
+			xnode_style = xmlNewNode (NULL, "style");
+			xmlAddChild (xnode, xnode_style);
+
+			xnode_style_prop = xmlNewNode (NULL, "width");
+			xmlNodeSetContent (xnode_style_prop, g_strdup_printf ("%f", priv->style->width));
+			xmlAddChild (xnode_style, xnode_style_prop);
+
+			xnode_style_prop = xmlNewNode (NULL, "stroke-color");
+			xmlNodeSetContent (xnode_style_prop, g_strdup (priv->style->stroke_color));
+			xmlAddChild (xnode_style, xnode_style_prop);
+
+			xnode_style_prop = xmlNewNode (NULL, "fill-color");
+			xmlNodeSetContent (xnode_style_prop, g_strdup (priv->style->fill_color));
+			xmlAddChild (xnode_style, xnode_style_prop);
+		}
+
+	if (priv->label != NULL)
+		{
+			xmlNode *xnode_label;
+			xmlNode *xnode_label_prop;
+
+			xnode_label = xmlNewNode (NULL, "label");
+			xmlAddChild (xnode, xnode_label);
+
+			xnode_label_prop = xmlNewNode (NULL, "field");
+			xmlNodeSetContent (xnode_label_prop, g_strdup (priv->label->field));
+			xmlAddChild (xnode_label, xnode_label_prop);
+		}
+
 	return xnode;
 }
 
@@ -212,20 +255,28 @@ GtkGisLayerSource
 /**
  * gtk_gis_layer_fill_from_source:
  * @layer: a #GtkGisLayer object.
+ * @label: a pointer to a #GtkGisLayerLabel struct.
  *
  * Loads the #GtkGisLayer's content from the associated #GtkGisLayerSource.
  * Contents loaded before will be lost.
  */
 void
-gtk_gis_layer_fill_from_source (GtkGisLayer *layer)
+gtk_gis_layer_fill_from_source (GtkGisLayer *layer, GtkGisLayerLabel *label)
 {
 	GtkGisLayerPrivate *priv;
+	gchar *field;
 
 	g_return_if_fail (IS_GTK_GIS_LAYER (layer));
 
 	priv = GTK_GIS_LAYER_GET_PRIVATE (layer);
 
-	priv->geometries = gtk_gis_layer_source_get_geometries (priv->source, priv->name);
+	field = NULL;
+	if (label->field != NULL && g_strcmp0 (label->field, "") != 0)
+		{
+			field = g_strdup (label->field);
+		}
+
+	priv->geometries = gtk_gis_layer_source_get_geometries (priv->source, priv->name, field);
 }
 
 /**
@@ -446,6 +497,38 @@ gtk_gis_layer_set_style (GtkGisLayer *layer, GtkGisLayerStyle style)
 	priv->style = g_memdup (&new_style, sizeof (GtkGisLayerStyle));
 }
 
+/**
+ * gtk_gis_layer_get_label:
+ * @layer: a #GtkGisLayer object.
+ *
+ */
+GtkGisLayerLabel
+*gtk_gis_layer_get_label (GtkGisLayer *layer)
+{
+	GtkGisLayerPrivate *priv;
+	GtkGisLayerLabel *label;
+
+	g_return_val_if_fail (IS_GTK_GIS_LAYER (layer), NULL);
+
+	return label;
+}
+
+/**
+ * gtk_gis_layer_set_label:
+ * @layer: a #GtkGisLayer object.
+ * @label:
+ *
+ */
+void
+gtk_gis_layer_set_label (GtkGisLayer *layer, GtkGisLayerLabel *label)
+{
+	GtkGisLayerPrivate *priv;
+
+	g_return_if_fail (IS_GTK_GIS_LAYER (layer));
+
+	priv->label = g_memdup (label, sizeof (GtkGisLayerLabel));
+}
+
 /**
  * gtk_gis_layer_draw:
  * @layer: a #GtkGisLayer object.
@@ -475,7 +558,7 @@ gtk_gis_layer_draw (GtkGisLayer *layer, GooCanvasItem *root, GtkGisScale *scale)
 			return;
 		}
 
-	gtk_gis_layer_fill_from_source (layer);
+	gtk_gis_layer_fill_from_source (layer, priv->label);
 
 	priv->layer_item = goo_canvas_group_new (root, NULL);
 
@@ -483,7 +566,6 @@ gtk_gis_layer_draw (GtkGisLayer *layer, GooCanvasItem *root, GtkGisScale *scale)
 	while (cur != NULL)
 		{
 			item = gtk_gis_geometry_draw ((GtkGisGeometry *)cur->data, scale, *priv->style);
-
 			if (item != NULL)
 				{
 					goo_canvas_item_add_child (priv->layer_item, item, -1);
diff --git a/src/layer.h b/src/layer.h
index da1c173..8e34461 100644
--- a/src/layer.h
+++ b/src/layer.h
@@ -71,7 +71,7 @@ gchar *gtk_gis_layer_get_name (GtkGisLayer *layer);
 
 GtkGisLayerSource *gtk_gis_layer_get_source (GtkGisLayer *layer);
 
-void gtk_gis_layer_fill_from_source (GtkGisLayer *layer);
+void gtk_gis_layer_fill_from_source (GtkGisLayer *layer, GtkGisLayerLabel *label);
 
 void gtk_gis_layer_save (GtkGisLayer *layer,
                          GtkGisLayerSource *source);
@@ -94,6 +94,9 @@ void gtk_gis_layer_set_editable (GtkGisLayer *layer,
 GtkGisLayerStyle *gtk_gis_layer_get_style (GtkGisLayer *layer);
 void gtk_gis_layer_set_style (GtkGisLayer *layer, GtkGisLayerStyle style);
 
+GtkGisLayerLabel *gtk_gis_layer_get_label (GtkGisLayer *layer);
+void gtk_gis_layer_set_label (GtkGisLayer *layer, GtkGisLayerLabel *label);
+
 void gtk_gis_layer_draw (GtkGisLayer *layer, GooCanvasItem *root, GtkGisScale *scale);
 
 
diff --git a/src/layersource.c b/src/layersource.c
index ff83156..551068d 100644
--- a/src/layersource.c
+++ b/src/layersource.c
@@ -32,7 +32,8 @@ static void gtk_gis_layer_source_init (GtkGisLayerSource *gtk_gis_layer_source);
 
 static GSList
 *gtk_gis_layer_source_get_geometries_from_ogr (GtkGisLayerSource *source,
-                                               const gchar *name);
+                                               const gchar *name,
+                                               const gchar *label_fieldname);
 static GSList
 *gtk_gis_layer_source_get_geometries_from_gdal (GtkGisLayerSource *source,
                                                 const gchar *name);
@@ -123,7 +124,8 @@ xmlNode
  */
 GSList
 *gtk_gis_layer_source_get_geometries (GtkGisLayerSource *source,
-                                      const gchar *name)
+                                      const gchar *name,
+                                      const gchar *label_fieldname)
 {
 	GSList *geometries = NULL;
 
@@ -131,7 +133,7 @@ GSList
 
     if (priv->datasource != NULL)
 		{
-			geometries = gtk_gis_layer_source_get_geometries_from_ogr (source, name);
+			geometries = gtk_gis_layer_source_get_geometries_from_ogr (source, name, label_fieldname);
 		}
 	else if (priv->dataset != NULL)
 		{
@@ -312,7 +314,8 @@ gtk_gis_layer_source_set_gdal_dataset (GtkGisLayerSource *source,
 
 static GSList
 *gtk_gis_layer_source_get_geometries_from_ogr (GtkGisLayerSource *source,
-                                               const gchar *name)
+                                               const gchar *name,
+                                               const gchar *label_fieldname)
 {
 	GSList *geometries = NULL;
 
@@ -322,6 +325,8 @@ static GSList
 	OGRGeometryH poGeometry;
 	GtkGisGeometry *geometry;
 
+	gint field_index;
+
 	gdouble fixy;
 
 	GtkGisLayerSourcePrivate *priv = GTK_GIS_LAYER_SOURCE_GET_PRIVATE (source);
@@ -341,6 +346,7 @@ static GSList
 			fixy = priv->max_extent->max_y + priv->max_extent->min_y;
 		//}
 
+	field_index = -1;
 	while ((feature = OGR_L_GetNextFeature (layer)) != NULL)
 		{
 			poGeometry = OGR_F_GetGeometryRef (feature);
@@ -424,6 +430,17 @@ static GSList
 						}
 				}
 
+			if (geometry != NULL
+			    && label_fieldname != NULL
+			    && g_strcmp0 (label_fieldname, "") != 0)
+				{
+					field_index = OGR_F_GetFieldIndex (feature, label_fieldname);
+					if (field_index > -1)
+						{
+							gtk_gis_geometry_set_label (geometry, OGR_F_GetFieldAsString (feature, field_index));
+						}
+				}
+
 			geometries = g_slist_append (geometries, geometry);
 		}
 
diff --git a/src/layersource.h b/src/layersource.h
index 50108c3..b62067c 100644
--- a/src/layersource.h
+++ b/src/layersource.h
@@ -69,7 +69,8 @@ GType gtk_gis_layer_source_get_type (void) G_GNUC_CONST;
 xmlNode *gtk_gis_layer_source_get_xml (GtkGisLayerSource *source);
 
 GSList *gtk_gis_layer_source_get_geometries (GtkGisLayerSource *source,
-                                             const gchar *name);
+                                             const gchar *name,
+                                             const gchar *label_fieldname);
 
 GtkGisLayerGeometryType gtk_gis_layer_source_get_layer_geometry_type (GtkGisLayerSource *source,
                                                                       const gchar *name);
-- 
2.49.0