# Filling a polygon with lines using Postgis

I need to calculate a specific distance in an area. The distance is calculated from parallel lines in a polygon, And I need to find out how many parallel lines (with x meters distance to each other) can a fill in a polygon. Is there some ready function for this operation in postgis or mapscript? Or do I need to implement it myself?

Here is sample image for what I want to do: I want to calculate how many orange lines can I put in polygon, and total length of these lines.

• Can you share the image through an alternative image hoster? Apr 24 '12 at 11:35
• imageshack.us/photo/my-images/11/questionvt.png i want to calculate how many orange lines can i put in polygon, and total length of these lines Apr 24 '12 at 11:44

This can be done quite easy in SQL

All the below examples can be tested directly on http://postgisonline.org/map.php. Just paste the query and press Map1

``````SELECT GENERATE_SERIES(FLOOR(ST_YMin(the_polygon))::int , CEILING(ST_YMax(the_polygon))::int,200) y_value, ST_XMin(the_polygon) x_min, ST_XMax(the_polygon) x_max from
(SELECT the_geom AS the_polygon FROM lakes) l
``````

Next step is to build lines from those coordinates and and use ST_Intersection to only get the parts of the lines intersecting the polygon:

``````SELECT ST_Intersection(the_geom, the_polygon)  AS the_geom FROM
(SELECT the_polygon, ST_Setsrid(ST_MakeLine(ST_MakePoint(x_min, y_value),ST_MakePoint(x_max, y_value) ), ST_Srid(the_polygon)) AS the_geom FROM
(SELECT the_polygon, GENERATE_SERIES(FLOOR(ST_YMin(the_polygon))::int , CEILING(ST_YMax(the_polygon))::int,200) y_value, ST_XMin(the_polygon) x_min, ST_XMax(the_polygon) x_max from
(SELECT the_geom AS the_polygon FROM lakes) l
)c
) lines
``````

Then, at last we can just sum all the lengths. So what you have got is a query looking like this doing the whole operation:

``````SELECT SUM(ST_Length(the_geom)) FROM
(SELECT ST_Intersection(the_geom, the_polygon)  AS the_geom FROM
(SELECT the_polygon, ST_Setsrid(ST_MakeLine(ST_MakePoint(x_min, y_value),ST_MakePoint(x_max, y_value) ), ST_Srid(the_polygon)) AS the_geom FROM
(SELECT the_polygon, GENERATE_SERIES(FLOOR(ST_YMin(the_polygon))::int , CEILING(ST_YMax(the_polygon))::int,200) y_value, ST_XMin(the_polygon) x_min, ST_XMax(the_polygon) x_max from
(SELECT the_geom AS the_polygon FROM lakes) l
)c
) lines
) intersection_lines
``````

edit

This was the length part of your problem mentioned in the end of the question. To count the number of lines is no problem of course. Then just use count(*) on the top row.

HTH

Nicklas

• Awesome answer. On a side note, how do you secure your postgisonline environment against malicious use? Do you simply raise an error when keywords like drop, update, insert and the like are used? Apr 24 '12 at 13:52
• @chriserik, Thanks :-). The only thing I have done is using database permissions to stop things like that. Since I have given out every detail about how the site is built here: blog.jordogskog.no/2010/06/15/what-is-behind-postgisonline-org and in the documentaion on the site including the code behind, I guess it is quite easy-hacked if someone really wat to. But it has been running for about 2 years now without any maintenance, so I guess people are more friendly out there then you might expect :-) Apr 24 '12 at 14:01
• that was a perfect answer for me, thank you Nicklas. what about, if i have a sample line for the angle of these orange lines? could i draw lines in a specific angle? like in the picture imageshack.us/photo/my-images/441/question2r.png Apr 24 '12 at 15:00
• @NicklasAvén, thanks for the link to your blog entry (i should have easily been able to find by myself, shame on me ;))! Apr 24 '12 at 15:18
• That sounds lika a good approach. But ST_rotate will rotate around origo, not around the center of your polygon. But you can fors move it in distance and direction from the centroid of the polygon to origo. With ST_Affine you can do all the moving and rotation "all in one", but I find it very hard to construct the right ST_Affine arguments. Apr 25 '12 at 8:15