This took a while to automate because of GDAL 1.5, so here it is:

If you think this fits in the TextSymbolizer documentation 
(http://trac.mapnik.org/wiki/TextSymbolizer), just tell me. Corrections 
welcomed.

PostGIS only
============

TextSymbolizer with polygon geometries:

Default position for labels in polygons is polygon's centroid. If you want your 
label to be placed on the surface of the polygon you can use the 
ST_PointOnSurface function.

1. Create a geometry field "point_on_surface" in the same table/layer
2. Run "update table_with_polygons set 
point_on_surface=ST_PointOnSurface(the_geom)" on your database
3. Use the generated points to draw the labels

Would you like to automate this, use a trigger to call a function like:

<code>
CREATE OR REPLACE FUNCTION coloma_point_on_surface() RETURNS "trigger" AS
$BODY$
BEGIN
  NEW.point_on_surface:=ST_PointOnSurface(NEW.the_geom);
  RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION coloma_point_on_surface() OWNER TO postgres;

CREATE TRIGGER table_with_polygons_point_on_surface
BEFORE INSERT OR UPDATE ON table_with_polygons FOR EACH ROW
EXECUTE PROCEDURE coloma_point_on_surface();
</code>


Workaround for GDAL < 1.6.0:

  * GDAL < 1.6.0 won't let you select which column to use for the geometry, so 
perhaps selecting
    the "point_on_surface" geometry field as the main geometry.

1. Create a Character Varying field "point_on_surface"
2. Modify the above code to look like this:

<code>
-- Use ST_GeomFromText('point_on_surface', SRS) to get the geometry back
--   where SRS is the same as the layer SRS, i.e. 23031
CREATE OR REPLACE FUNCTION coloma_point_on_surface() RETURNS "trigger" AS
$BODY$
BEGIN
  -- Store geometry as text so GDAL uses "the_geom" as the feature geometry
  NEW.point_on_surface:=ST_AsText(ST_PointOnSurface(NEW.the_geom));
  RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION coloma_point_on_surface() OWNER TO postgres;

CREATE TRIGGER table_with_polygons_point_on_surface
BEFORE INSERT OR UPDATE ON table_with_polygons FOR EACH ROW
EXECUTE PROCEDURE coloma_point_on_surface();
</code>



> -----Mensaje original-----
> De: [email protected]
> [mailto:[email protected]] En nombre de
> [email protected]
> Enviado el: lunes, 31 de mayo de 2010 10:17
> Para: [email protected]
> CC: [email protected]
> Asunto: Re: [Mapnik-users] TextSymbolizer label placement for polygon
>
> Hi Numenor,
>
> ST_PointOnSurface helped a lot. It first killed postgres
> because I tried using it directly in the SQL for ogcserver. I
> tried adding a new field "point_on_surface" and updating it.
> It works flawlessly!
>
> Still, this is not as optimal as a good label placement
> algorithm, but will work meanwhile...
>
> And by the way, the polygon inside polygon ended being an
> internal polygon sharing limits with the bigger one, but NOT
> overlapping. So this is "solved" too.
>
> Thank you very much for your help!
>
>
> > -----Mensaje original-----
> > De: numenor [mailto:[email protected]]
> > Enviado el: viernes, 28 de mayo de 2010 14:55
> > Para: Clos Crespo, Manel
> > CC: [email protected]
> > Asunto: Re: [Mapnik-users] TextSymbolizer label placement
> for polygon
> >
> > Hi Manel,
> >
> > On Fri, 28 May 2010 14:21:08 +0200, <[email protected]> wrote:
> > > I've two problems with label placement:
> > >
> > > 1) When the centroid is outside of the polygon the label
> > will appear to
> > be
> > > labeling just another polygon (confusing).
> >
> > Maybe the SQL extension function 'ST_PointOnSurface' can
> help you (at
> > least as a workaround), if you use PostGIS as data source.
> For a given
> > surface, this function returns a point which is guaranteed to
> > lie on the
> > surface. It does not guarantee any more, but with PostGIS,
> for me for
> > convex shapes the labels appear similarly placed as when
> > using ST_Centroid
> > (or mapnik's algorithm), more or less in the middle.
> >
> > > 2) When a polygon is inside a bigger one, and they both
> > have a similar
> > > centroid, both labels will end in the smaller polygon (really
> > confusing),
> > > and the bigger one will appear to have no label at all
> > (more confusion).
> >
> > Is this problem solvable at all, in general? What if the
> > outer polygon is
> > completely covered by smaller polygons?
> >
> > If this can happen, maybe a better solution would be to label
> > the border
> > of the polygon, as is often done for borders between administrative
> > entities.
> >
> > If you know which smaller polygons lie inside the bigger one,
> > you could
> > subtract their area from the bigger one, and then use
> > ST_PointOnSurface on
> > the result to get the point for placement of the label.
> This might of
> > course be computationally expensive ...
> >
> > Hope this helps,
> > --
> > Holger Schöner - [email protected]
> >
> _______________________________________________
> Mapnik-users mailing list
> [email protected]
> https://lists.berlios.de/mailman/listinfo/mapnik-users
>
_______________________________________________
Mapnik-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/mapnik-users

Reply via email to