static PyObject *Polygon_simplify(Polygon *self, PyObject *args) { gpc_polygon *ret, *lop, *rop, *tmp, *p = self->p; int i; if (p->num_contours <= 0) { Py_INCREF(Py_None); return Py_None; } if (! (lop = poly_p_new())) return Polygon_Raise(ERR_MEM); if (! (rop = poly_p_new())) return Polygon_Raise(ERR_MEM); if (! (ret = poly_p_new())) return Polygon_Raise(ERR_MEM); /* find first contour which is not a hole */ i = 0; while ((i < p->num_contours) && (p->hole[i] == 1)) i++; if (i < p->num_contours) gpc_add_contour(lop, p->contour+i, 1); /* then try to add other contours */ for (i++; i < p->num_contours; i++) { if (p->hole[i] == 0) { gpc_free_polygon(rop); gpc_free_polygon(ret); gpc_add_contour(rop, (p->contour+i), 0); gpc_polygon_clip(GPC_UNION, lop, rop, ret); tmp = lop; lop = ret; ret = tmp; } } /* then try to cut out holes */ for (i = 0; i < p->num_contours; i++) { if (p->hole[i] == 1) { gpc_free_polygon(rop); gpc_free_polygon(ret); gpc_add_contour(rop, (p->contour+i), 0); gpc_polygon_clip(GPC_DIFF, lop, rop, ret); tmp = lop; lop = ret; ret = tmp; } } gpc_free_polygon(self->p); free(self->p); self->p = lop; gpc_free_polygon(ret); free(ret); gpc_free_polygon(rop); free(rop); self->bbValid = 0; return Py_BuildValue("O", Py_None); }
gpc_polygon *geomShapeToGpcPolygon( GeomShape *shape ) { gpc_polygon *gpcPoly = new gpc_polygon; memset( gpcPoly, 0, sizeof(gpc_polygon) ); for( int i=0; i<shape->polyCount(); i++ ) { // MAKE a gpc contour from out polygon. This requires a loop because // we have DVec3 and they want DVec2 gpc_vertex_list contour; contour.num_vertices = shape->polys[i]->vertCount(); contour.vertex = (gpc_vertex *)new double[ 2 * contour.num_vertices ]; for( int j=0; j<contour.num_vertices; j++ ) { contour.vertex[j].x = shape->polys[i]->verts[j].x; contour.vertex[j].y = shape->polys[i]->verts[j].y; } gpc_add_contour( gpcPoly, &contour, shape->holes[i] ); // We think that gpc_add_contour is copying the data so now we must free the buffer // that was used to convert into 2D delete contour.vertex; } return gpcPoly; }
void Polygon2d::addHole(std::vector<std::pair<double,double>> vec) { gpc_vertex_list list={static_cast<int>(vec.size()),reinterpret_cast<gpc_vertex*>(&vec[0])}; gpc_add_contour(&polygon,&list,1); gpc_free_tristrip(&strip); gpc_polygon_to_tristrip(&polygon,&strip); }
static const paths& clip(const Paths& paths, unsigned int count, const path& edge, ClipType clip_type) { gpc_vertex_list gvl = {1, memory::malloc<gpc_vertex>()}; gpc_polygon subject = {0, nullptr, nullptr}; gpc_polygon clip = {0, nullptr, nullptr}; gpc_polygon result = {0, nullptr, nullptr}; for (unsigned int i = 0; i < count; ++i) gpc_add_contour(&subject, &gpc::fill(gvl, paths[i]), 0); gpc_add_contour(&clip, &gpc::fill(gvl, edge), 0); gpc_op op; switch (clip_type) { default: case ctInt: op = GPC_INT; break; case ctDiff: op = GPC_DIFF; break; case ctXor: op = GPC_XOR; break; case ctUnion: op = GPC_UNION; break; } gpc_polygon_clip(op, &subject, &clip, &result); static class paths clipped_paths; clipped_paths.clear(); for (int i = 0; i < result.num_contours; ++i) { vertex_set* clipped_result = new vertex_set; const gpc_vertex_list& gvl = result.contour[i]; for (int i = 0; i < gvl.num_vertices; ++i) clipped_result->append(gvl.vertex[i].x, gvl.vertex[i].y); clipped_paths.append(clipped_result); } gpc_free_polygon(&result); gpc_free_polygon(&clip); gpc_free_polygon(&subject); memory::free(gvl.vertex, gvl.num_vertices); return clipped_paths; }
static PyObject *Polygon_addContour(Polygon *self, PyObject *args) { #ifdef WITH_NUMERIC PyObject *a=NULL; gpc_vertex_list *vl; int hole = 0; if (! PyArg_ParseTuple(args, "O|i", &a, &hole)) return Polygon_Raise(ERR_ARG); if ((a = PyArray_ContiguousFromObject(a, PyArray_DOUBLE, 2, 2)) == NULL) return Polygon_Raise(ERR_ARG); if (((PyArrayObject *)a)->nd != 2) return Polygon_Raise(ERR_ARG); if (((PyArrayObject *)a)->dimensions[1] != 2) return Polygon_Raise(ERR_ARG); vl = PyMem_New(gpc_vertex_list, 1); vl->num_vertices = ((PyArrayObject *)a)->dimensions[0]; vl->vertex = PyMem_New(gpc_vertex, vl->num_vertices); memcpy((vl->vertex), (((PyArrayObject *)a)->data), 2*vl->num_vertices*sizeof(double)); Py_DECREF(a); #else PyObject *list=NULL, *flist, *point=NULL, *X, *Y; gpc_vertex_list *vl; gpc_vertex *v; int i, imax, hole = 0; if (! PyArg_ParseTuple(args, "O|i", &list, &hole)) return Polygon_Raise(ERR_ARG); if (! PySequence_Check(list)) return Polygon_Raise(ERR_ARG); flist = PySequence_Fast(list, "this is not a sequence"); if ((! flist) || ((imax = PySequence_Length(flist)) <= 2)) return Polygon_Raise(ERR_INV); vl = PyMem_New(gpc_vertex_list, 1); vl->num_vertices = imax; vl->vertex = v = PyMem_New(gpc_vertex, imax); for (i=0; i<imax; i++) { point = PySequence_Fast(PySequence_Fast_GET_ITEM(flist, i), "this is not a point"); if ((!point) || (PySequence_Length(point) != 2)) return Polygon_Raise(ERR_INV); v->x = PyFloat_AsDouble(X = PyNumber_Float(PySequence_Fast_GET_ITEM(point, 0))); v->y = PyFloat_AsDouble(Y = PyNumber_Float(PySequence_Fast_GET_ITEM(point, 1))); v++; Py_DECREF(X); Py_DECREF(Y); Py_DECREF(point); } Py_DECREF(flist); #endif /* WITH_NUMERIC */ gpc_add_contour(self->p, vl, hole); self->bbValid = 0; PyMem_Free(vl->vertex); PyMem_Free(vl); Py_INCREF(Py_None); return Py_None; }
static int Ladd(lua_State *L) /** add(p,c,[hole]) */ { int i,n; gpc_vertex_list c; gpc_polygon *p=Pget(L,1); luaL_checktype(L,2,LUA_TTABLE); n=luaL_getn(L,2)/2; c.num_vertices=n; c.vertex=malloc(c.num_vertices*sizeof(*c.vertex)); for (i=0; i<n; i++) { lua_rawgeti(L,2,2*i+1); c.vertex[i].x=lua_tonumber(L,-1); lua_rawgeti(L,2,2*i+2); c.vertex[i].y=lua_tonumber(L,-1); lua_pop(L,2); } gpc_add_contour(p,&c,lua_toboolean(L,3)); free(c.vertex); lua_settop(L,1); return 1; }
static PyObject *Polygon_cloneContour(Polygon *self, PyObject *args) { int con, i, hole=-1; double xs=1.0, ys=1.0; gpc_vertex_list *vl = NULL, *vlnew = NULL; gpc_polygon *p = ((Polygon *)self)->gpc_p; if (! PyArg_ParseTuple(args, "i|ddi", &con, &xs, &ys, &hole)) return Polygon_Raise(ERR_ARG); if (con < 0) con += p->num_contours; if ((con >= p->num_contours) || (con < 0)) return Polygon_Raise(ERR_IND); vl = (p->contour)+con; vlnew = PyMem_New(gpc_vertex_list, 1); vlnew->num_vertices = vl->num_vertices; vlnew->vertex = PyMem_New(gpc_vertex, vlnew->num_vertices); for (i=0; i < vl->num_vertices; i++) { vlnew->vertex[i].x = vl->vertex[i].x + xs; vlnew->vertex[i].y = vl->vertex[i].y + ys; } gpc_add_contour(p, vlnew, p->hole[con]); self->bbValid = 0; PyMem_Free(vlnew->vertex); PyMem_Free(vlnew); return Py_BuildValue("i", (p->num_contours)-1); }
/* read a regular grid description and create corresponding polygons */ PolyObject *TestPolyReader( char *name, /* file name to read */ BoundingBox *bbox, /* bounding box of interest - ignore if NULL */ MapProjInfo *mpinfo) { PolyObject *poly; Shape *shp; PolyShape *ps; MapProjInfo *map; int nObjects; int nv, np; int c, r; char mesg[256]; char *earth_ellipsoid; char *gname; char cname[NAMLEN3+1]; int ctype; double p_alp; double p_bet; double p_gam; double xcent; double ycent; double xorig; double yorig; double xcell=10000; double ycell=10000; int ncols; int nrows; int nthik; char *ioapi_sphere="+a=6370997.0,+b=6370997.0"; map = getNewMap(); if (map == NULL) { sprintf(mesg,"getNewMap error for %s", name); goto error; } //ellipsoid doesn't matter for a grid - the IO/API supports sphere only if ((map->earth_ellipsoid = (char *) strdup(ioapi_sphere)) == NULL) { sprintf(mesg,"Allocation error for map's ellipsoid"); goto error; } map->p_alp = mpinfo->p_alp; map->p_bet = mpinfo->p_bet; map->p_gam = mpinfo->p_gam; map->xcent = mpinfo->xcent; map->ycent = mpinfo->ycent; map->xcell = mpinfo->xcell; map->ycell = mpinfo->ycell; map->xorig = mpinfo->xorig; map->yorig = mpinfo->yorig; map->ctype = mpinfo->ctype; map->gridname = (char *) strdup(mpinfo->gridname); map->ncols = mpinfo->ncols; map->nrows = mpinfo->nrows; nObjects = 1; poly = getNewPoly(nObjects); if (poly == NULL) { sprintf(mesg,"Cannot allocate POLY struct"); goto error; } poly->nSHPType = SHPT_POLYGON; poly->map = map; poly->bb = newBBox(xorig, yorig, xorig+xcell, yorig+ycell); nv = 4; /* num vertices */ np = 1; /* num parts of shape */ ps = getNewPolyShape(np); ps->num_contours = 0; /* we need to reset, since gpc_add_contour increments num_contours */ /* clockwise shape */ shp = getNewShape(nv); shp->vertex[0].x = xorig; shp->vertex[0].y = yorig; shp->vertex[1].x = xorig; shp->vertex[1].y = yorig+ycell*2; shp->vertex[2].x = xorig+xcell*2; shp->vertex[2].y = yorig + ycell*2; shp->vertex[3].x = xorig+xcell*2; shp->vertex[3].y = yorig; gpc_add_contour(ps, shp, NOT_A_HOLE); polyShapeIncl(&(poly->plist), ps, NULL); /* counter clockwise hole */ shp = getNewShape(nv); shp->vertex[0].x = xorig; shp->vertex[0].y = yorig; shp->vertex[1].x = shp->vertex[0].x + xcell; shp->vertex[1].y = shp->vertex[0].y; shp->vertex[2].x = shp->vertex[1].x; shp->vertex[2].y = shp->vertex[1].y + ycell; shp->vertex[3].x = shp->vertex[0].x; shp->vertex[3].y = shp->vertex[2].y; gpc_add_contour(ps, shp, NOT_A_HOLE); polyShapeIncl(&(poly->plist), ps, NULL); return poly; error: WARN(mesg); return NULL; /* we should never get here */ }
// make a gpc_polygon for a closed polyline contour // approximates arcs with multiple straight-line segments // if icontour = -1, make polygon with all contours, // combining intersecting contours if possible // returns data on arcs in arc_array // int CPolyLine::MakeGpcPoly( int icontour, CArray<CArc> * arc_array ) { if( m_gpc_poly->num_contours ) FreeGpcPoly(); if( !GetClosed() && (icontour == (GetNumContours()-1) || icontour == -1)) return 1; // error // initialize m_gpc_poly m_gpc_poly->num_contours = 0; m_gpc_poly->hole = NULL; m_gpc_poly->contour = NULL; int n_arcs = 0; int first_contour = icontour; int last_contour = icontour; if( icontour == -1 ) { first_contour = 0; last_contour = GetNumContours() - 1; } if( arc_array ) arc_array->SetSize(0); int iarc = 0; for( int icont=first_contour; icont<=last_contour; icont++ ) { // make gpc_polygon for this contour gpc_polygon * gpc = new gpc_polygon; gpc->num_contours = 0; gpc->hole = NULL; gpc->contour = NULL; // first, calculate number of vertices in contour int n_vertices = 0; int ic_st = GetContourStart(icont); int ic_end = GetContourEnd(icont); for( int ic=ic_st; ic<=ic_end; ic++ ) { int style = side_style[ic]; int x1 = corner[ic].x; int y1 = corner[ic].y; int x2, y2; if( ic < ic_end ) { x2 = corner[ic+1].x; y2 = corner[ic+1].y; } else { x2 = corner[ic_st].x; y2 = corner[ic_st].y; } if( style == STRAIGHT ) n_vertices++; else { // style is ARC_CW or ARC_CCW int n; // number of steps for arcs n = (abs(x2-x1)+abs(y2-y1))/(CArc::MAX_STEP); n = max( n, CArc::MIN_STEPS ); // or at most 5 degrees of arc n_vertices += n; n_arcs++; } } // now create gcp_vertex_list for this contour gpc_vertex_list * g_v_list = new gpc_vertex_list; g_v_list->vertex = (gpc_vertex*)calloc( sizeof(gpc_vertex), n_vertices ); g_v_list->num_vertices = n_vertices; int ivtx = 0; for( int ic=ic_st; ic<=ic_end; ic++ ) { int style = side_style[ic]; int x1 = corner[ic].x; int y1 = corner[ic].y; int x2, y2; if( ic < ic_end ) { x2 = corner[ic+1].x; y2 = corner[ic+1].y; } else { x2 = corner[ic_st].x; y2 = corner[ic_st].y; } if( style == STRAIGHT ) { g_v_list->vertex[ivtx].x = x1; g_v_list->vertex[ivtx].y = y1; ivtx++; } else { // style is arc_cw or arc_ccw int n; // number of steps for arcs n = (abs(x2-x1)+abs(y2-y1))/(CArc::MAX_STEP); n = max( n, CArc::MIN_STEPS ); // or at most 5 degrees of arc double xo, yo, theta1, theta2, a, b; a = fabs( (double)(x1 - x2) ); b = fabs( (double)(y1 - y2) ); if( style == CPolyLine::ARC_CW ) { // clockwise arc (ie.quadrant of ellipse) int i=0, j=0; if( x2 > x1 && y2 > y1 ) { // first quadrant, draw second quadrant of ellipse xo = x2; yo = y1; theta1 = pi; theta2 = pi/2.0; } else if( x2 < x1 && y2 > y1 ) { // second quadrant, draw third quadrant of ellipse xo = x1; yo = y2; theta1 = 3.0*pi/2.0; theta2 = pi; } else if( x2 < x1 && y2 < y1 ) { // third quadrant, draw fourth quadrant of ellipse xo = x2; yo = y1; theta1 = 2.0*pi; theta2 = 3.0*pi/2.0; } else { xo = x1; // fourth quadrant, draw first quadrant of ellipse yo = y2; theta1 = pi/2.0; theta2 = 0.0; } } else { // counter-clockwise arc int i=0, j=0; if( x2 > x1 && y2 > y1 ) { xo = x1; // first quadrant, draw fourth quadrant of ellipse yo = y2; theta1 = 3.0*pi/2.0; theta2 = 2.0*pi; } else if( x2 < x1 && y2 > y1 ) { xo = x2; // second quadrant yo = y1; theta1 = 0.0; theta2 = pi/2.0; } else if( x2 < x1 && y2 < y1 ) { xo = x1; // third quadrant yo = y2; theta1 = pi/2.0; theta2 = pi; } else { xo = x2; // fourth quadrant yo = y1; theta1 = pi; theta2 = 3.0*pi/2.0; } } // now write steps for arc if( arc_array ) { arc_array->SetSize(iarc+1); (*arc_array)[iarc].style = style; (*arc_array)[iarc].n_steps = n; (*arc_array)[iarc].xi = x1; (*arc_array)[iarc].yi = y1; (*arc_array)[iarc].xf = x2; (*arc_array)[iarc].yf = y2; iarc++; } for( int is=0; is<n; is++ ) { double theta = theta1 + ((theta2-theta1)*(double)is)/n; double x = xo + a*cos(theta); double y = yo + b*sin(theta); if( is == 0 ) { x = x1; y = y1; } g_v_list->vertex[ivtx].x = x; g_v_list->vertex[ivtx].y = y; ivtx++; } } } if( n_vertices != ivtx ) ASSERT(0); // add vertex_list to gpc gpc_add_contour( gpc, g_v_list, 0 ); // now clip m_gpc_poly with gpc, put new poly into result gpc_polygon * result = new gpc_polygon; if( icontour == -1 && icont != 0 ) gpc_polygon_clip( GPC_DIFF, m_gpc_poly, gpc, result ); // hole else gpc_polygon_clip( GPC_UNION, m_gpc_poly, gpc, result ); // outside // now copy result to m_gpc_poly gpc_free_polygon( m_gpc_poly ); delete m_gpc_poly; m_gpc_poly = result; gpc_free_polygon( gpc ); delete gpc; free( g_v_list->vertex ); free( g_v_list ); } return 0; }
void clo_clip ( int *np, float *xp, float *yp, char *sysp, char *bounds, char *name, int *nclip, int *maxpts, int *iret ) /************************************************************************ * clo_clip * * * * This routine performs clipping of a polygon against a specified * * bounds area. * * * * void clo_clip ( np, xp, yp, sysp, bounds, name, nclip, * * maxpts, iret ) * * * * Input parameters: * * *np int Number of polygon points * * *xp float X array of polygon points * * *yp float Y array of polygon points * * *sysp char Polygon points coordinate system* * *bounds char Bounds name * * *name char Clipping area tag * * * * Output parameters: * * *nclip int Number of resulting contours * * *maxpts int Maximum number of points for any* * contour in the resulting polygon* * *iret int Return code * * = 0: normal * * * ** * * Log: * * B. Yin/SAIC 9/04 Created * ***********************************************************************/ { int ier, ii; float *xnormal, *ynormal; gpc_polygon gpc_poly, gpc_poly_bnds, gpc_poly_tmp; gpc_vertex_list verts; /*---------------------------------------------------------------------*/ strcpy ( sysin, sysp ); /* * Convert incoming coordinate system to sys_N (normalized). */ G_MALLOC ( xnormal, float, *np, "CLO_CLIP: xnormal" ); G_MALLOC ( ynormal, float, *np, "CLO_CLIP: ynormal" ); gtrans ( sysp, sys_N, np, xp, yp, xnormal, ynormal, &ier, strlen(sysp), strlen(sys_N) ); /* * Fill GPC polygon structure with incoming points. */ gpc_poly.num_contours = 0; gpc_poly.hole = (int*)NULL; gpc_poly.contour = (gpc_vertex_list*)NULL; verts.vertex = (gpc_vertex*)NULL; verts.num_vertices = 0; gpc_cvlist ( *np, xnormal, ynormal, &verts, &ier ); gpc_add_contour ( &gpc_poly, &verts, G_FALSE ); /* * Create a GPC polygon for the bounds. */ clo_clipbnds ( bounds, name, &gpc_poly_bnds, &ier ); /* * Clip */ gpc_polygon_clip ( GPC_INT, &gpc_poly, &gpc_poly_bnds, &gpc_poly_tmp ); /* * Remove holes. Holes are ignored in this release. */ gpc_poly_results.num_contours = 0; gpc_poly_results.hole = (int*)NULL; gpc_poly_results.contour = (gpc_vertex_list*)NULL; for ( ii = 0; ii < gpc_poly_tmp.num_contours; ii++ ) { if ( gpc_poly_tmp.hole [ ii ] == G_FALSE ) { gpc_add_contour ( &gpc_poly_results, &gpc_poly_tmp.contour [ ii ], G_FALSE ); } } /* * Get the number of contours in the resulting polygon * and the maximum number of pointers of any contour */ *nclip = gpc_poly_results.num_contours; *maxpts = 0; for ( ii = 0; ii < *nclip; ii++ ) { *maxpts = MAX ( *maxpts, gpc_poly_results.contour [ ii ].num_vertices ); } /* * Release memory */ gpc_free_polygon ( &gpc_poly_bnds ); gpc_free_polygon ( &gpc_poly_tmp ); gpc_free_polygon ( &gpc_poly ); free ( verts.vertex ); G_FREE ( xnormal, float ); G_FREE ( ynormal, float ); *iret = 0; }
static void clo_clipbnds ( char *bounds, char *name, gpc_polygon *polygon, int *iret ) /************************************************************************ * clo_clipbnds * * * * This routine puts all bound parts into a polygon. * * * * void clo_clipbnds ( bounds, name, polygon, iret ) * * * * Input parameters: * * *bounds char Bounds name * * *name char Clipping area tag * * * * Output parameters: * * *polygon gpc_polygon Resulting polygon * * *iret int Return code * * = 0: normal * * * ** * * Log: * * B. Yin/SAIC 9/04 Created * ***********************************************************************/ { int minp, maxp, next, npts, ier; float *xlat, *ylon, *xnormal, *ynormal; float filter; gpc_vertex_list verts; /*---------------------------------------------------------------------*/ /* * Set bounds type and tag */ clo_bstype ( bounds, &ier ); clo_bstag ( name, &ier ); /* * Initialization */ minp = 0; maxp = LLMXPT; filter = 0.0F; next = 0; G_MALLOC ( xlat, float, maxp, "CLO_CLIPBNDS: xlat" ); G_MALLOC ( ylon, float, maxp, "CLO_CLIPBNDS: ylon" ); polygon->num_contours = 0; polygon->hole = (int*)NULL; polygon->contour = (gpc_vertex_list*)NULL; /* * Read each bounds part and put it in a gpc polygon */ clo_bgnext ( &minp, &maxp, &filter, &npts, xlat, ylon, &next ); while ( next == 0 ) { /* * Convert bounds coordinate system to sys_N */ G_MALLOC ( xnormal, float, npts, "CLO_CLIPBNDS: xnormal" ); G_MALLOC ( ynormal, float, npts, "CLO_CLIPBNDS: ynormal" ); gtrans ( sys_M, sys_N, &npts, xlat, ylon, xnormal, ynormal, &ier, strlen(sys_M), strlen(sys_N) ); /* * Create GPC polygon structures for bounds. */ verts.vertex = (gpc_vertex*)NULL; verts.num_vertices = 0; gpc_cvlist ( npts, xnormal, ynormal, &verts, &ier ); /* * Holes are not considered */ gpc_add_contour ( polygon, &verts, G_FALSE ); /* * Free memory */ free ( verts.vertex ); G_FREE ( xnormal, float ); G_FREE ( ynormal, float ); clo_bgnext ( &minp, &maxp, &filter, &npts, xlat, ylon, &next ); } G_FREE ( xlat, float ); G_FREE ( ylon, float ); *iret = 0; }
static void create_grid (local_data_t *local_data, spatial_search_t *spatial_index) { double dx, dy; guint h, v, npolys; double grid_min_x, grid_min_y; guint row, col; #if DEBUG g_debug ("----- ENTER create_grid (%s)", MODEL_NAME); #endif /* How many grid squares do we need to cover the horizontal and vertical * extents of the study area? */ dx = spatial_index->max_x - spatial_index->min_x; dy = spatial_index->max_y - spatial_index->min_y; h = (guint)ceil(dx / local_data->grid_size); v = (guint)ceil(dy / local_data->grid_size); npolys = h * v; #if DEBUG g_debug ("creating %ux%u=%u grid squares to cover %g km x %g km area", h, v, npolys, dx, dy); #endif /* Define one corner of the grid. */ grid_min_x = spatial_index->min_x - 0.5 * (h * local_data->grid_size - dx); grid_min_y = spatial_index->min_y - 0.5 * (v * local_data->grid_size - dy); /* Create the polygons. */ for (row = 0; row < v; row++) { double y0, y1; y0 = grid_min_y + row * local_data->grid_size; y1 = y0 + local_data->grid_size; for (col = 0; col < h; col++) { double x0, x1; gpc_vertex_list *contour; gpc_polygon *grid_square; x0 = grid_min_x + col * local_data->grid_size; x1 = x0 + local_data->grid_size; contour = g_new (gpc_vertex_list, 1); contour->num_vertices = 4; contour->vertex = g_new (gpc_vertex, 4); contour->vertex[0].x = x0; contour->vertex[0].y = y0; contour->vertex[1].x = x1; contour->vertex[1].y = y0; contour->vertex[2].x = x1; contour->vertex[2].y = y1; contour->vertex[3].x = x0; contour->vertex[3].y = y1; /* Wrap the contour in a polygon object. */ grid_square = gpc_new_polygon (); gpc_add_contour (grid_square, contour, 0); g_ptr_array_add (local_data->polys, grid_square); } } g_assert (local_data->polys->len == npolys); /* Now that we know the number of polygons, initialize the unit_count, * ninfected, nvaccinated, and ndestroyed arrays. */ g_assert (local_data->unit_count == NULL); local_data->max_nvertices = 4; local_data->unit_count = g_new0 (guint, npolys); local_data->ninfected = g_new0 (double, npolys); local_data->nvaccinated = g_new0 (double, npolys); local_data->ndestroyed = g_new0 (double, npolys); #if DEBUG g_debug ("----- EXIT create_grid (%s)", MODEL_NAME); #endif return; }
int main ( void ) /************************************************************************ * TESTGPC * * * * This program tests the GPC contributed library public functions. * * * ** * * Log: * * D.W.Plummer/NCEP 2/04 * * D.W.Plummer/NCEP 10/06 Added GPC_SET_EPSILON * ***********************************************************************/ { int ii, cont, numsub, which, ier; int operation, readholeflag, writeholeflag, hole; int nverts=0; double e; char select[8]; float xv[LLMXPT], yv[LLMXPT]; char filnam[256], buffer[80]; int pagflg; char errgrp[8]; FILE *fpread, *fpwrite; gpc_polygon subject_polygon, clip_polygon, result_polygon; gpc_vertex_list contour; /*---------------------------------------------------------------------*/ cont = G_FALSE; /* * Structure initializations. */ subject_polygon.num_contours = 0; subject_polygon.hole = (int*)NULL; subject_polygon.contour = (gpc_vertex_list*)NULL; clip_polygon.num_contours = 0; result_polygon.num_contours = 0; contour.vertex = (gpc_vertex*)NULL; contour.num_vertices = 0; while ( cont == G_FALSE ) { printf ( "\n\n" ); printf ( "*** ORIGINAL GPC PUBLIC FUNCTIONS ***\n"); printf ( " 1 = GPC_READ_POLYGON 2 = GPC_WRITE_POLYGON \n"); printf ( " 3 = GPC_ADD_CONTOUR 4 = GPC_POLYGON_CLIP \n"); printf ( " 5 = GPC_FREE_POLYGON \n"); printf ( "*** GPC PUBLIC FUNCTION ADD-ONS ***\n"); printf ( " 11 = GPC_CREATE_VERTEX_LIST \n"); printf ( " 12 = GPC_GET_VERTEX_LIST \n"); printf ( " 13 = GPC_GET_VERTEX_AREA \n"); printf ( " 14 = GPC_SET_EPSILON \n"); printf ( "*** HELP ***\n"); printf ( " 99 = HELP on INPUT FILE FORMATS \n"); printf ( "\n" ); printf ( "Select a subroutine number or type EXIT: " ); scanf ( " %s", select ); switch ( select[0] ) { case 'e': case 'E': cont = G_TRUE; default: numsub = atoi ( select ); break; } /*---------------------------------------------------------------------*/ if ( numsub == 1 ) { printf("Make sure your polygon file is in the proper format:\n"); printf("<num-contours>\n"); printf("<num-vertices-in-first-contour>\n"); printf("[<first-contour-hole-flag>]\n"); printf("<vertex-list>\n"); printf("<num-vertices-in-second-contour>\n"); printf("[<second-contour-hole-flag>]\n"); printf("<vertex-list> \n"); printf("etc...\n"); printf ( "Enter filename to read polygon from : \n"); scanf ( " %s", filnam ); printf ( "Enter whether file format contains hole flags (%d-FALSE,%d-TRUE) :\n", G_FALSE, G_TRUE ); scanf ( " %d", &readholeflag ); printf ( "Enter which polygon (%d-SUBJECT,%d-CLIP) :\n", SUBJECT, CLIP ); scanf ( " %d", &which ); fpread = (FILE *)cfl_ropn ( filnam, "", &ier ); if ( ier == G_NORMAL ) { if ( which == SUBJECT ) gpc_read_polygon ( fpread, readholeflag, &subject_polygon ); else if ( which == CLIP ) gpc_read_polygon ( fpread, readholeflag, &clip_polygon ); else printf("Invalid polygon type\n"); cfl_clos ( fpread, &ier ); } else { printf("Unable to open file %s\n", filnam ); } } /*---------------------------------------------------------------------*/ if ( numsub == 2 ) { printf ( "Enter filename to write polygon to : \n"); scanf ( " %s", filnam ); printf ( "Enter the write hole flag (%d-FALSE,%d-TRUE):\n", G_FALSE, G_TRUE ); scanf ( " %d", &writeholeflag ); printf ( "Enter which polygon (%d-SUBJECT,%d-CLIP,%d-RESULT):\n", SUBJECT, CLIP, RESULT ); scanf ( " %d", &which ); fpwrite = (FILE *)cfl_wopn ( filnam, &ier ); if ( ier == G_NORMAL ) { if ( which == SUBJECT ) gpc_write_polygon ( fpwrite, writeholeflag, &subject_polygon ); else if ( which == CLIP ) gpc_write_polygon ( fpwrite, writeholeflag, &clip_polygon ); else if ( which == RESULT ) gpc_write_polygon ( fpwrite, writeholeflag, &result_polygon ); else printf("Invalid polygon type\n"); cfl_clos ( fpwrite, &ier ); } else { printf("Unable to open file %s\n", filnam ); } } /*---------------------------------------------------------------------*/ if ( numsub == 3 ) { if ( nverts == 0 ) { printf("Must first create a vertex list (option 11)\n"); } else { printf ( "Enter which polygon (%d-SUBJECT,%d-CLIP,%d-RESULT) to add vertex list to:\n", SUBJECT, CLIP, RESULT ); scanf ( " %d", &which ); printf ( "Enter the hole flag (%d-HOLE,%d-NOT A HOLE):\n", G_TRUE, G_FALSE ); scanf ( " %d", &hole ); if ( which == SUBJECT ) { gpc_add_contour ( &subject_polygon, &contour, hole ); } else if ( which == CLIP ) { gpc_add_contour ( &clip_polygon, &contour, hole ); } else { printf("Invalid polygon\n"); } } } /*---------------------------------------------------------------------*/ if ( numsub == 4 ) { printf ( "Enter operation (%d-GPC_DIFF,%d-GPC_INT,%d-GPC_XOR,%d-GPC_UNION):\n", GPC_DIFF, GPC_INT, GPC_XOR, GPC_UNION ); scanf ( " %d", &operation ); gpc_polygon_clip ( operation, &subject_polygon, &clip_polygon, &result_polygon ); } /*---------------------------------------------------------------------*/ if ( numsub == 5 ) { printf ( "Enter which polygon (%d-SUBJECT,%d-CLIP,%d-RESULT,%d-ALL) to free contours:\n ", SUBJECT, CLIP, RESULT, ALL ); scanf ( " %d", &which ); if ( which == SUBJECT || which == ALL ) { if ( subject_polygon.num_contours != 0 ) gpc_free_polygon ( &subject_polygon ); } else if ( which == CLIP || which == ALL ) { if ( clip_polygon.num_contours != 0 ) gpc_free_polygon ( &clip_polygon ); } else if ( which == RESULT || which == ALL ) { if ( result_polygon.num_contours != 0 ) gpc_free_polygon ( &result_polygon ); } } /*---------------------------------------------------------------------*/ if ( numsub == 11 ) { printf ( "Enter either the number of points in polygon (to be followed by entering the points), or a filename to read points from: \n"); scanf ( " %s", filnam ); cst_numb ( filnam, &nverts, &ier ); if ( ier == 0 ) { for ( ii = 0; ii < nverts; ii++ ) scanf ( "%f %f", &(xv[ii]), &(yv[ii]) ); if ( contour.vertex != (gpc_vertex*)NULL ) free ( contour.vertex ); gpc_cvlist ( nverts, xv, yv, &contour, &ier ); } else { printf ( "Note that the file format is simply a list of coordinate pairs separated by whitespace.\nThe number of points will be counted automatically. For instance, a file containing:\n0 0\n0 1\n1 1\nyields a vertex list of three points.\n\n"); nverts = 0; fpread = (FILE *)cfl_tbop ( filnam, "", &ier ); if ( ier == G_NORMAL ) { cfl_trln ( fpread, sizeof(buffer), buffer, &ier ); while ( ier == 0 ) { sscanf ( buffer, "%f %f", &(xv[nverts]), &(yv[nverts]) ); nverts += 1; cfl_trln ( fpread, sizeof(buffer), buffer, &ier ); } printf("EOF reached in file %s, number of vertices = %d\n", filnam, nverts ); cfl_clos( fpread, &ier ); if ( contour.vertex != (gpc_vertex*)NULL ) free ( contour.vertex ); gpc_cvlist ( nverts, xv, yv, &contour, &ier ); } } } /*---------------------------------------------------------------------*/ if ( numsub == 12 ) { gpc_gvlist ( &contour, &nverts, xv, yv, &ier ); printf("gpc_gvlist, ier = %d\n", ier ); printf("Number of vertices = %d\n", nverts ); for ( ii = 0; ii < nverts; ii++ ) printf ( "%d - %f %f\n", ii, xv[ii], yv[ii] ); } /*---------------------------------------------------------------------*/ if ( numsub == 13 ) { printf ( "Area of contour is %f\n", gpc_gvarea(&contour) ); } /*---------------------------------------------------------------------*/ if ( numsub == 14 ) { scanf ( " %lf", &e ); gpc_set_epsilon ( e ); } /*---------------------------------------------------------------------*/ if ( numsub == 99 ) { pagflg = G_FALSE; strcpy ( errgrp, "TESTGPC" ); ip_help ( errgrp, &pagflg, &ier, strlen(errgrp) ); } /*---------------------------------------------------------------------*/ } if ( subject_polygon.num_contours != 0 ) gpc_free_polygon ( &subject_polygon ); if ( clip_polygon.num_contours != 0 ) gpc_free_polygon ( &clip_polygon ); if ( result_polygon.num_contours != 0 ) gpc_free_polygon ( &result_polygon ); if ( contour.vertex != (gpc_vertex*)NULL ) free ( contour.vertex ); return(0); }
void clo_blasso ( char *bndtyp, char *key, int *npts, char *btags, gpc_polygon *union_poly, int *iret ) /************************************************************************ * clo_blasso * * * * This function takes a string of bound tags, semi-colon separated, and* * returns a polygon structure from the union of the polygons designated* * by the bound tags. A return code of 1 due to a bad bounds key tag * * could mean the tag name (eg., <FIPS>) is invalid and/or the tag value* * (eg., 51059 -- a FIPS code) is invalid. Processing continues, so the* * invoking routine may also want to check the number of polygons for 0,* * in which case it would most likely be caused by an invalid tag name. * * * * Note that the tag name may or may not be enclosed with '<' and '>'. * * If it is not, they will be added to the tag name. * * * * clo_blasso ( bndtyp, key, npts, btags, union_poly, iret ) * * * * Input parameters: * * *bndtyp char Bounds file alias name (eg., WBCMZ_BNDS)* * *key char Search tag name in bounds file * * (eg., <FIPS> or FIPS, <STATE> or STATE)* * *npts int No. of bounds tag values in string btags* * *btags char Bounds tag values, delimited by ";" * * (eg., 51059;51057;51053) * * * * Output parameters: * * *union_poly gpc_polygon GPC polygon structure of union * * iret int Return code * * = 0 Normal * * = 1 No bound area found for a tag * * due to bad tag name or value * * = -1 Bounds file open error return * * or illegal bounds name * * * ** * * Log: * * F. J. Yen/NCEP 1/05 * * F. J. Yen/NCEP 2/05 Increased size of btagkey; Enclosed tag * * name with '<' and '>' if missing. * * J. Wu/SAIC 6/05 remove reference to LLMXPT * * F.Yen&D.Plummer/NCEP 7/05 Redesigned for performance. * * D.W.Plummer/NCEP 8/05 Add final GPC_UNION to rm spurious pts * ***********************************************************************/ { char **arrptr, btagkey[80]; char *tag_start = { "<" }; char *tag_end = { ">" }; int ii, maxexp, minp, ier, ierro, mxpts, end; int narr, numTmp, len, hole, initl; float *xTmp, *yTmp; float rlatmn, rlonmn, dlatmx, dlonmx, filter; gpc_polygon polygon; gpc_vertex_list verts; /*---------------------------------------------------------------------*/ *iret = 0; ier = 0; minp = 0; hole = 0; filter = 0.0; maxexp = 400; /* * Initalize the gpc polygon structure variables */ union_poly->num_contours = 0; union_poly->hole = (int *)NULL; union_poly->contour = (gpc_vertex_list *)NULL; clo_bstype ( bndtyp , &ier ); /* Set the bounds file */ if ( ier != 0 ) { *iret = -1; return; } /* * Set the bounds area */ rlatmn = -90.0; dlatmx = +90.0; rlonmn = -180.0; dlonmx = +180.0; clo_bsarea ( &rlatmn, &rlonmn, &dlatmx, &dlonmx, &ier ); /* * Initialize the clo library */ clo_init ( &ier); /* * Allocate memory */ clo_qmxpts ( "BOUNDS", &mxpts, &ier ); G_MALLOC ( xTmp, float, mxpts, "CLO_BLASSO" ); G_MALLOC ( yTmp, float, mxpts, "CLO_BLASSO" ); /* * Break apart the bounds tag values */ arrptr = (char **)malloc(*npts * sizeof(char *)); for (ii = 0; ii < *npts; ii++) { arrptr[ii] = (char *) malloc(maxexp); } cst_clst ( btags, ';', " ", *npts, maxexp, arrptr, &narr, &ier ); /* * initialize single bounds polygon */ polygon.num_contours = 0; polygon.hole = (int *)NULL; polygon.contour = (gpc_vertex_list *)NULL; /* * Loop over bounds tag values */ for (ii=0;ii < narr; ii++) { cst_rmbl ( arrptr[ii], arrptr[ii], &len, &ier ); if ( len > 0 ) { ierro = 0; /* * Create the key tag to search on ( eg. <FIPS>51097 ). First, * check for '<' at beginning of tag. Add it if it isn't there. */ btagkey[0] = '\0'; if( key[0] != '<' ) { strcpy( btagkey, tag_start ); } strcat ( btagkey, key ); /* * Check for '>' at end of key tag. Add it if it isn't there. */ end = strlen ( key ); if ( key [ end - 1 ] != '>' ) { strcat ( btagkey, tag_end ); } strcat ( btagkey, arrptr[ii]); clo_bstype ( bndtyp , &ier ); /* Set the bounds file */ clo_bstag ( btagkey, &ier ); /* Set the bounds key tag (eg <FIPS>51097 ) */ /* * Find the bound key tag polygon */ initl = 1; while ( ierro == 0 ) { /* * Get next bounds */ clo_bgnext (&minp, &mxpts, &filter, &numTmp, xTmp, yTmp, &ierro ); if ( initl == 1 ) { initl = 0; if ( ierro != 0 ) { /* * No bound area (polygon) found for current bounds * key tag in btagkey due to either an invalid tag * name (eg, <FIPS> or <STATE>) and/or invalid tag * value (ie, if the tag name is <FIPS>, the tag * value would be a FIPS code such as 13009). */ *iret = 1; } } if ( ierro == 0 ) { /* * initialize vertex list */ verts.vertex = (gpc_vertex*)NULL; verts.num_vertices =0; gpc_cvlist (numTmp, xTmp, yTmp, &verts, &ier ); gpc_add_contour ( &polygon, &verts, hole); free ( verts.vertex ); } } /* end for while loop */ } /* end for length check */ } /* end for loop */ /* * union the polygon with a NULL polygon (union) to get the union */ gpc_polygon_clip (GPC_UNION, &polygon, union_poly, union_poly ); gpc_free_polygon ( &polygon); gpc_polygon_clip (GPC_UNION, &polygon, union_poly, union_poly ); /* * Free memory space. */ G_FREE ( xTmp, float ); G_FREE ( yTmp, float ); for ( ii = 0; ii < *npts; ii++ ) { free ( arrptr[ii] ); } free ( arrptr); }
PolyObject *FractionalVegetationReader(char *name, /* the name of the file to read */ MapProjInfo * map, /* the map projection of the file to read */ BoundingBox * bbox, /* bounding box of interest - ignore if NULL */ MapProjInfo * bbox_mproj /* the map projection of the bounding box */ ) { FILE *fp; int buffer[5001]; /* latitude values from -180 to 179.856 degrees */ PolyObject *poly; Shape *shp; PolyShape *ps; int nObjects; int nv, np; int c, r, recno, n, ichr, i, j, ival; int icol, irow; int ncnt, nmax; char **list; char mesg[256]; /** projection parameters **/ char *gname; char cname[NAMLEN3 + 1]; int ctype = LATGRD3; double p_alp = 0.0; double p_bet = 0.0; double p_gam = 0.0; double xcent = 0.0; double ycent = 0.0; double xorig = 0.0; double yorig = 0.0; double xcell = 0.144; double ycell = 0.144; int ncols; int nrows; int nthik = 1; /** range of domain **/ double lon_min = -128.0; double lon_max = -65.0; double lat_min = 23.0; double lat_max = 51.0; /* fill the map projection structure - doing it this way won't allow for a * custom map projection */ map = getNewMap(); map->p_alp = p_alp; map->p_bet = p_bet; map->p_gam = p_gam; map->xcent = xcent; map->ycent = ycent; map->xcell = xcell; map->ycell = ycell; map->xorig = xorig; map->yorig = yorig; map->ctype = ctype; map->gridname = "Fractional Vegetation"; map->ncols = ncols; map->nrows = nrows; /** get range values from environment variable DOMAIN_RANGE **/ if(strlistc("DOMAIN_RANGE", "Comma separated list of range values", &nmax, &ncnt, &list)) { if(ncnt == 4) { lon_min = (double) atof(list[0]); lon_max = (double) atof(list[1]); lat_min = (double) atof(list[2]); lat_max = (double) atof(list[3]); } else { printf("DOMAIN_RANGE not defined, using default\n"); } } /** check domain limits **/ if(lon_min < -180.0 || lon_max > 180.0 || lat_min < -89.928 || lat_max > 179.856) { printf("Invalid DOMAIN_RANGE values, using default\n"); lon_min = -128.0; lon_max = -65.0; lat_min = 23.0; lat_max = 51.0; } /** round off minimum range values to cell **/ icol = (lon_min + 180.0) / xcell; lon_min = -180.0 + icol * xcell; irow = (lat_min + 89.928) / ycell; lat_min = -89.928 + irow * ycell; /** compute number of rows and columns **/ ncols = (int) ((lon_max - lon_min) / xcell) + 1; nrows = (int) ((lat_max - lat_min) / ycell) + 1; if(getenv(name) == NULL) { sprintf(mesg, "Env. var. \"%s\" not set", name); goto error; } gname = (char *) strdup(getenv(name)); nObjects = nrows * ncols; poly = getNewPoly(nObjects); if(poly == NULL) { sprintf(mesg, "Cannot allocate POLY struct"); goto error; } poly->nSHPType = SHPT_POLYGON; poly->map = map; poly->name = (char *) strdup(gname); poly->bb = newBBox(lon_min, lat_min, lon_min + xcell * ncols, lat_min + ycell * nrows); nv = 4; np = 1; for(r = irow; r < irow + nrows; r++) { for(c = icol; c < icol + ncols; c++) { ps = getNewPolyShape(np); ps->num_contours = 0; /* we need to reset, since gpc_add_contour increments num_contours */ shp = getNewShape(nv); shp->vertex[0].x = -180 + c * xcell; shp->vertex[0].y = -89.928 + r * ycell; shp->vertex[1].x = shp->vertex[0].x + xcell; shp->vertex[1].y = shp->vertex[0].y; shp->vertex[2].x = shp->vertex[1].x; shp->vertex[2].y = shp->vertex[1].y + ycell; shp->vertex[3].x = shp->vertex[0].x; shp->vertex[3].y = shp->vertex[2].y; gpc_add_contour(ps, shp, SOLID_POLYGON); polyShapeIncl(&(poly->plist), ps, NULL); } } /** add attributes from file **/ /* open grid file */ if((fp = fopen(gname, "r")) == NULL) { sprintf(mesg, "Cannot open grid file %s", poly->name); goto error; } /*** create Attribute ***/ if(!poly->attr_hdr) { poly->attr_hdr = getNewAttrHeader(); } n = addNewAttrHeader(poly->attr_hdr, "VEGFRAC", FTInteger); if(!poly->attr_val) { poly->attr_hdr->attr_desc[0]->category = 10; poly->attr_val = (AttributeValue **) malloc(nObjects * sizeof(AttributeValue *)); for(recno = 0; recno < nObjects; recno++) { if((poly->attr_val[recno] = (AttributeValue *) malloc(n * sizeof(AttributeValue))) == NULL) { sprintf(mesg, "%s", "Attribute allocation error"); goto error; } for(j = 0; j < n; j++) { poly->attr_val[recno][j].str = NULL; } } } /** set attribute values **/ recno = 0; for(r = 0; r < 1250; r++) { /** read row of data **/ for(i = 0; i < 5001; i++) { buffer[i] = fgetc(fp); } if(r >= irow && r < irow + nrows) { for(c = icol; c < icol + ncols; c++) { ival = 0; if(buffer[2 * c] > 48 && buffer[2 * c] <= 57) ival = 10 * (buffer[2 * c] - 48); if(buffer[2 * c + 1] > 48 && buffer[2 * c + 1] <= 57) ival += (buffer[2 * c + 1] - 48); if(ival == 0) ival = -1; poly->attr_val[recno][0].ival = ival; recno++; if(recno > nObjects) printf("number of objects exceed max %d \n", recno); } } } if(recno != nObjects) printf("number of objects != attributes read\n"); /* close grid file */ fclose(fp); return poly; error: WARN(mesg); return NULL; /* we should never get here */ }
Polygon2d::Polygon2d(std::vector<std::pair<double,double>> &verts):polygon{0,0,0},strip{0,0} { gpc_vertex_list list={static_cast<int>(verts.size()),reinterpret_cast<gpc_vertex*>(&verts[0])}; gpc_add_contour(&polygon,&list,0); gpc_polygon_to_tristrip(&polygon,&strip); }