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

