Point inside polygon and distance point to polygon

Discussions about CSEntry
Post Reply
Posts: 441
Joined: December 19th, 2011, 6:26 pm
Location: HAITI

Point inside polygon and distance point to polygon

Post by htuser » April 8th, 2019, 10:31 pm

Dear Cspro Developer Team,
Maybe i'm the CSProuser who request more functionalities and features to you, and since you're a small team with limited ressources, it's impossible to respond to all CSProusers request. Latest weeks i'm trying to do my best to implement some functionalities such as Point inside polygon and distance point to polygon, this using the CSPro Programming Language. But, also, since i'm a Agricultural economics engineer, i'm limited in programming. I learned C/C++ at bachelor degree, years ago.

This would be worse if i used CAPI systems who don't have any code editor, compiler and don't supporting any know programming language.

Fortunately, CSPro Programming Language helped me to maintain a certain level in programming, mainly with your incredible support. And also, i realize that, if i spend more time to design advanced function in CSPro Logic, rather than waiting to you this will help me a lot in advanced programming. Also, the community will have access to them. However, since CSPro logic doesn't support object programming, such as Python or R, it limit us...

Following my early year post: http://csprousers.org/forum/viewtopic.php?f=1&t=2858, i would like to implement some algorithms from:
a.- http://geomalgorithms.com
b.- https://stackoverflow.com/questions/924 ... de-polygon

in CSPro Logic.

For this 2D polygon, i would like to:
a.- transform it in point (there's a lot of tools to to that in QGIS and the attribute table of points can be exported to Excel);
store these points in CSdb in a table having a table named polygon with 4 columns: pk_number, polygon_id, X, Y (i hope CSdb and Excel2CSPro will
support stored in multiple tables and columns soon. Normally, i can load the Excel-CSV file in an independent sqlite database, since Josh discourage to create other table in CSdb or CSlog, but i don't know how to synchronize an independent sqlite database to CSWeb..., so i maintain using CSdb);
b.- sync this CSdb to CSweb;
c.- using this CSdb in CSEntry application as external dictionary;
d.- using sqlquery to retrieve theses points as a numeric array : Does CSPro support array with decimal? In Javascript, it's easy:
https://stackoverflow.com/questions/703 ... javascript.
e.- the point that i want to know if it's inside the polygon is this recorded in CSEntry (application or in paradata).
f.- it's possible to transform this array of polygon in a object or similar element in CSPro logic? It's possible to implement this algorithm in CSPro logic:
(algorithm from: http://geomalgorithms.com )

Code: Select all


// wn_PnPoly(): winding number test for a point in a polygon
//      Input:   P = a point,
//               V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
//      Return:  wn = the winding number (=0 only when P is outside)
wn_PnPoly( Point P, Point* V, int n )
    int    wn = 0;    // the  winding number counter

    // loop through all edges of the polygon
    for (int i=0; i<n; i++) {   // edge from V[i] to  V[i+1]
        if (V[i].y <= P.y) {          // start y <= P.y
            if (V[i+1].y  > P.y)      // an upward crossing
                 if (isLeft( V[i], V[i+1], P) > 0)  // P left of  edge
                     ++wn;            // have  a valid up intersect
        else {                        // start y > P.y (no test needed)
            if (V[i+1].y  <= P.y)     // a downward crossing
                 if (isLeft( V[i], V[i+1], P) < 0)  // P right of  edge
                     --wn;            // have  a valid down intersect
    return wn;
Also can you advise me on better idea to do this?

Thanks in advance for your support!

Posts: 2034
Joined: May 5th, 2014, 12:49 pm
Location: Washington DC

Re: Point inside polygon and distance point to polygon

Post by josh » April 9th, 2019, 7:21 am

First off, no need to involve sql in this at all. For those who are used to using sql database, a lookup file in CSPro is the rough equivalent of a table in a sql database and loadcase is how you do the equivalent of a select.

You can easily store your polygons in a lookup file where each row represents a point in the polygon. The points are grouped by polygon id. The file below contains two polygons: one with 6 points and another with 5.

Code: Select all

id	lon	            lat
1	-76.94626808	38.83964076
1	-76.94137573	38.83295506
1	-76.93030357	38.83001315
1	-76.92635536	38.8328882
1	-76.93279266	38.84284967
1	-76.94626808	38.83964076
2	-76.9330287	38.84532311
2	-76.92815781	38.84532311
2	-76.92815781	38.84980183
2	-76.9330287	38.84980183
2	-76.9330287	38.84532311
You can create a file like the above in Excel. Then create a CSPro dictionary to match it. It should have a single id-item (polygon id) and a repeating record that contains two items: longitude and latitude. Use Excel2CSPro to convert the spreadsheet to a CSPro data file.

Since this is a CSPro data file you can use it with sync to download/upload the file if your polygons change.

You can load a polygon from your lookup file using loadcase. For example, if you want to load the polygon with ID 1 you would do:
POLY_ID = 1;
loadcase(POLYS_DICT, POLY_ID);
No need to convert to arrays since the repeating record already acts like an array. You can get the length with count() and you can reference the nth latitude and longitude for the polygon using subscripts. If your record is POLYS_REC then you would use count(POLYS_REC) to get the number of points in the polygon. If your items are POLY_LON and POLY_LAT then you can use POLY_LON(1) and POLY_LAT(1) to get the coordinates of the first point in the polygon.

Now it is easy to port the point in polygon test from C to CSPro. Assume LON and LAT are the coordinates of the point you want to test and the polygon to test against has been loaded using loadcase so its coordinates are POLY_LON and POLY_LAT.
    numeric wn = 0;    // the  winding number counter
    numeric n = count(POLYS_REC) - 1;

    // loop through all edges of the polygon
    do numeric i=1 while i <= n    // edge from V to  V[i+1]
        if POLY_LAT(i) <= LAT then         // start y <= P.y
            if POLY_LAT(i+1) > LAT then      // an upward crossing
                 if isLeft(POLY_LON(i), POLY_LAT(i), POLY_LON(i+1), POLY_LAT(i+1), LON, LAT) > 0 then  // P left of  edge
                     wn = wn + 1;            // have  a valid up intersect
        else                         // start y > P.y (no test needed)
            if POLY_LAT(i+1)  <= LAT then     // a downward crossing
                 if isLeft(POLY_LON(i), POLY_LAT(i), POLY_LON(i+1), POLY_LAT(i+1), LON, LAT) < 0 then // P right of  edge
                     wn = wn -1;            // have  a valid down intersect

    if wn = 0 then
        errmsg("Point outside");
        errmsg("Point inside");

The function isLeft is defined as:

function isLeft(P0x, P0y, P1x, P1y, P2x, P2y)
    isLeft = (P1x - P0x) * (P2y - P0y)
            - (P2x -  P0x) * (P1y - P0y);

I'm attaching a simple test project that puts this all together.
(13.13 KiB) Downloaded 70 times

Posts: 441
Joined: December 19th, 2011, 6:26 pm
Location: HAITI

Re: Point inside polygon and distance point to polygon

Post by htuser » April 9th, 2019, 11:48 am

A lot of highly thanks to you Josh!

This example show to us how the CSPro Programming Language is enough to implement advanced algorithms.
So it's better to try solving some request in CSPro Logic rather than asking you specific CSPro function.
Also, for you, it's very important to continue improving CSPro Programming Language.
Best Regards,

Posts: 367
Joined: July 9th, 2012, 11:32 am
Location: Islamabad, Pakistan

Re: Point inside polygon and distance point to polygon

Post by khurshid.arshad » April 13th, 2019, 2:48 am

Dear Haiti user and Josh

Thank you for the file. I was also trying to do this and now it is done.

Thank you.


Post Reply