Should we add point_on_surface support to Mapnik's Symbolizers?

Dane


On May 31, 2010, at 4:15 AM, <[email protected]> 
<[email protected]> wrote:

> 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

_______________________________________________
Mapnik-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/mapnik-users

Reply via email to