6

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:

enter image description here

I want to calculate how many orange lines can I put in polygon, and total length of these lines.

9

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? – chriserik Apr 24 '12 at 13:52
  • 2
    @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 :-) – Nicklas Avén 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 – bahadir 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 ;))! – chriserik Apr 24 '12 at 15:18
  • 1
    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. – Nicklas Avén Apr 25 '12 at 8:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.