/****************************************************************************** * $Id: Shape_PointInPoly.cpp,v 1.2 2016-12-05 12:44:07 erouault Exp $ * * Project: Shapelib * Purpose: Commandline program to generate points-in-polygons from a * shapefile as a shapefile. * Author: Marko Podgorsek, d-mon@siol.net * ****************************************************************************** * Copyright (c) 2004, Marko Podgorsek, d-mon@siol.net * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see COPYING). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: Shape_PointInPoly.cpp,v $ * Revision 1.2 2016-12-05 12:44:07 erouault * * Major overhaul of Makefile build system to use autoconf/automake. * * * Warning fixes in contrib/ * * Revision 1.1 2004-01-09 16:47:57 fwarmerdam * New * */ static char rcsid[] = "$Id: Shape_PointInPoly.cpp,v 1.2 2016-12-05 12:44:07 erouault Exp $"; #include #include #include #include #define MAXINTERSECTIONPOINTS 255 enum loopDir { kExterior, kInterior, kError }; struct DPoint2d { DPoint2d() { x = y = 0.0; }; DPoint2d(double x, double y) { this->x = x; this->y = y; }; double x,y; }; struct IntersectPoint { IntersectPoint(void) { x = y = 0.0; boundry_nmb = 0; loopdirection = kError; }; double x,y; int boundry_nmb; loopDir loopdirection; }; loopDir LoopDirection(DPoint2d *vertices, int vertsize) { int i; double sum = 0.0; for(i=0;i0) return kInterior; else return kExterior; } DPoint2d CreatePointInPoly(SHPObject *psShape, int quality) { int i, j, k, end, vert, pointpos; double part, dx, xmin, xmax, ymin, ymax, y, x3, x4, y3, y4, len, maxlen = 0; DPoint2d *vertices; loopDir direction; IntersectPoint mp1, mp2, point1, point2, points[MAXINTERSECTIONPOINTS]; xmin = psShape->dfXMin; ymin = psShape->dfYMin; xmax = psShape->dfXMax; ymax = psShape->dfYMax; part = (ymax-ymin)/(quality+1); dx = xmax-xmin; for(i=0;inParts;j++) { if(j==psShape->nParts-1) end = psShape->nVertices; else end = psShape->panPartStart[j+1]; vertices = new DPoint2d [end-psShape->panPartStart[j]]; for(k=psShape->panPartStart[j],vert=0;kpadfX[k]; vertices[vert++].y = psShape->padfY[k]; } direction = LoopDirection(vertices, vert); for(k=0;k= y && y4 < y) || (y3 <= y && y4 > y)) //I check >= only once, because if it's not checked now (y3) it will be in the next iteration (which is y4 now) { point1.boundry_nmb = j; point1.loopdirection = direction; x3 = vertices[k].x; x4 = vertices[k+1].x; if(y3==y) { point1.y = y3; point1.x = x3; if(direction == kInterior) //add point 2 times if the direction is interior, so that the final count of points is even { points[pointpos++]=point1; } } else { point1.x = xmin+(((((x4-x3)*(y-y3))-((y4-y3)*(xmin-x3)))/((y4-y3)*dx))*dx); //striped down calculation of intersection of 2 lines point1.y = y; } points[pointpos++]=point1; } } delete [] vertices; } for(j=1;j0;k--) { if(points[k].x < points[k-1].x) { point1 = points[k]; points[k] = points[k-1]; points[k-1] = point1; } else { break; } } } for(j=0;j= maxlen) { maxlen = len; mp1 = point1; mp2 = point2; } } } } return DPoint2d((mp1.x+mp2.x)*0.5, (mp1.y+mp2.y)*0.5); } int main(int argc, char* argv[]) { if(argc != 3) { printf("Usage: %s shpfile_path quality\n", argv[0]); return 1; } int i, nEntities, quality; SHPHandle hSHP; SHPObject *psShape; DPoint2d pt; quality = atoi(argv[2]); hSHP = SHPOpen(argv[1], "rb"); SHPGetInfo(hSHP, &nEntities, NULL, NULL, NULL); printf("PointInPoly v1.0, by Marko Podgorsek\n----------------\n"); for( i = 0; i < nEntities; i++ ) { psShape = SHPReadObject( hSHP, i ); if(psShape->nSHPType == SHPT_POLYGON) { pt = CreatePointInPoly(psShape, quality); printf("%d: x=%f y=%f\n",i, pt.x,pt.y); } SHPDestroyObject( psShape ); } SHPClose(hSHP); return 0; }