int msProjectShape(projectionObj *in, projectionObj *out, shapeObj *shape) { #ifdef USE_PROJ int i; #ifdef USE_PROJ_FASTPATHS int j; if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) { for( i = shape->numlines-1; i >= 0; i-- ) { for( j = shape->line[i].numpoints-1; j >= 0; j-- ) { #define p_x shape->line[i].point[j].x #define p_y shape->line[i].point[j].y p_x *= MAXEXTENTby180; p_y = log(tan((90 + p_y) * M_PIby360)) * MS_RAD_TO_DEG; p_y *= MAXEXTENTby180; if (p_x > MAXEXTENT) p_x = MAXEXTENT; if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; if (p_y > MAXEXTENT) p_y = MAXEXTENT; if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; #undef p_x #undef p_y } } msComputeBounds( shape ); /* fixes bug 1586 */ return MS_SUCCESS; } #endif for( i = shape->numlines-1; i >= 0; i-- ) { if( shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON ) { if( msProjectShapeLine( in, out, shape, i ) == MS_FAILURE ) msShapeDeleteLine( shape, i ); } else if( msProjectLine(in, out, shape->line+i ) == MS_FAILURE ) { msShapeDeleteLine( shape, i ); } } if( shape->numlines == 0 ) { msFreeShape( shape ); return MS_FAILURE; } else { msComputeBounds( shape ); /* fixes bug 1586 */ return(MS_SUCCESS); } #else msSetError(MS_PROJERR, "Projection support is not available.", "msProjectShape()"); return(MS_FAILURE); #endif }
int msProjectShape(projectionObj *in, projectionObj *out, shapeObj *shape) { #ifdef USE_PROJ int i; for( i = shape->numlines-1; i >= 0; i-- ) { if( shape->type == MS_SHAPE_LINE || shape->type == MS_SHAPE_POLYGON ) { if( msProjectShapeLine( in, out, shape, i ) == MS_FAILURE ) msShapeDeleteLine( shape, i ); } else if( msProjectLine(in, out, shape->line+i ) == MS_FAILURE ) { msShapeDeleteLine( shape, i ); } } if( shape->numlines == 0 ) { msFreeShape( shape ); return MS_FAILURE; } else { msComputeBounds( shape ); /* fixes bug 1586 */ return(MS_SUCCESS); } #else msSetError(MS_PROJERR, "Projection support is not available.", "msProjectShape()"); return(MS_FAILURE); #endif }
static shapeObj *msGEOSGeometry2Shape_line(GEOSGeom g) { shapeObj *shape=NULL; int i; int numPoints; GEOSCoordSeq coords; if(!g) return NULL; numPoints = GEOSGetNumCoordinates(g); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(g); shape = (shapeObj *) malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_LINE; shape->line = (lineObj *) malloc(sizeof(lineObj)); shape->numlines = 1; shape->line[0].point = (pointObj *) malloc(sizeof(pointObj)*numPoints); shape->line[0].numpoints = numPoints; shape->geometry = (GEOSGeom) g; for(i=0; i<numPoints; i++) { GEOSCoordSeq_getX(coords, i, &(shape->line[0].point[i].x)); GEOSCoordSeq_getY(coords, i, &(shape->line[0].point[i].y)); /* GEOSCoordSeq_getZ(coords, i, &(shape->line[0].point[i].z)); */ } msComputeBounds(shape); return shape; }
static shapeObj *msGEOSGeometry2Shape_multipoint(GEOSGeom g) { int i; int numPoints; GEOSCoordSeq coords; GEOSGeom point; shapeObj *shape=NULL; if(!g) return NULL; numPoints = GEOSGetNumGeometries(g); /* each geometry has 1 point */ shape = (shapeObj *) malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_POINT; shape->line = (lineObj *) malloc(sizeof(lineObj)); shape->numlines = 1; shape->line[0].point = (pointObj *) malloc(sizeof(pointObj)*numPoints); shape->line[0].numpoints = numPoints; shape->geometry = (GEOSGeom) g; for(i=0; i<numPoints; i++) { point = (GEOSGeom) GEOSGetGeometryN(g, i); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(point); GEOSCoordSeq_getX(coords, 0, &(shape->line[0].point[i].x)); GEOSCoordSeq_getY(coords, 0, &(shape->line[0].point[i].y)); /* GEOSCoordSeq_getZ(coords, 0, &(shape->line[0].point[i].z)); */ } msComputeBounds(shape); return shape; }
int msHatchPolygon(imageObj *img, shapeObj *poly, double spacing, double width, double *pattern, int patternlength, double angle, colorObj *color) { assert(MS_RENDERER_PLUGIN(img->format)); msComputeBounds(poly); /* amount we should expand the bounding box by */ double exp = width * 0.7072; /* width and height of the bounding box we will be creating the hatch in */ int pw=(int)(poly->bounds.maxx-poly->bounds.minx+exp*2)+1; int ph=(int)(poly->bounds.maxy-poly->bounds.miny+exp*2)+1; /* position of the top-left corner of the bounding box */ double ox = poly->bounds.minx - exp; double oy = poly->bounds.miny - exp; //create a rectangular hatch of size pw,ph starting at 0,0 //the created hatch is of the size of the shape's bounding box mapserver::path_storage hatch = createHatch(ox,oy, img->refpt.x,img->refpt.y,pw,ph,angle,spacing); if(hatch.total_vertices()<=0) return MS_SUCCESS; //translate the hatch so it overlaps the current shape hatch.transform(mapserver::trans_affine_translation(ox,oy)); polygon_adaptor polygons(poly); if(patternlength>1) { //dash the hatch and render it clipped by the shape mapserver::conv_dash<mapserver::path_storage > dash(hatch); mapserver::conv_stroke<mapserver::conv_dash<mapserver::path_storage> > stroke(dash); for (int i=0; i<patternlength; i+=2) { if (i < patternlength-1) { dash.add_dash(pattern[i], pattern[i+1]); } } stroke.width(width); stroke.line_cap(mapserver::butt_cap); mapserver::conv_clipper<polygon_adaptor,mapserver::conv_stroke<mapserver::conv_dash<mapserver::path_storage> > > clipper(polygons,stroke, mapserver::clipper_and); renderPolygonHatches(img,clipper,color); } else { //render the hatch clipped by the shape mapserver::conv_stroke <mapserver::path_storage > stroke(hatch); stroke.width(width); stroke.line_cap(mapserver::butt_cap); mapserver::conv_clipper<polygon_adaptor,mapserver::conv_stroke<mapserver::path_storage> > clipper(polygons,stroke, mapserver::clipper_and); renderPolygonHatches(img,clipper,color); } //assert(prevCmd == mapserver::path_cmd_line_to); //delete lines; return MS_SUCCESS; }
static shapeObj *msGEOSGeometry2Shape_polygon(GEOSGeom g) { shapeObj *shape=NULL; lineObj line; int numPoints, numRings; int i, j; GEOSCoordSeq coords; GEOSGeom ring; if(!g) return NULL; shape = (shapeObj *) malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_POLYGON; shape->geometry = (GEOSGeom) g; /* exterior ring */ ring = (GEOSGeom) GEOSGetExteriorRing(g); numPoints = GEOSGetNumCoordinates(ring); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(ring); line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints); line.numpoints = numPoints; for(i=0; i<numPoints; i++) { GEOSCoordSeq_getX(coords, i, &(line.point[i].x)); GEOSCoordSeq_getY(coords, i, &(line.point[i].y)); /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */ } msAddLineDirectly(shape, &line); /* interior rings */ numRings = GEOSGetNumInteriorRings(g); for(j=0; j<numRings; j++) { ring = (GEOSGeom) GEOSGetInteriorRingN(g, j); if(GEOSisRing(ring) != 1) continue; /* skip it */ numPoints = GEOSGetNumCoordinates(ring); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(ring); line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints); line.numpoints = numPoints; for(i=0; i<numPoints; i++) { GEOSCoordSeq_getX(coords, i, &(line.point[i].x)); GEOSCoordSeq_getY(coords, i, &(line.point[i].y)); /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */ } msAddLineDirectly(shape, &line); } msComputeBounds(shape); return shape; }
int msUVRASTERLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record) { uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *) layer->layerinfo; lineObj line ; pointObj point; int i, j, k, x=0, y=0; long shapeindex = record->shapeindex; msFreeShape(shape); shape->type = MS_SHAPE_NULL; if( shapeindex < 0 || shapeindex >= uvlinfo->query_results ) { msSetError(MS_MISCERR, "Out of range shape index requested. Requested %ld\n" "but only %d shapes available.", "msUVRASTERLayerGetShape()", shapeindex, uvlinfo->query_results ); return MS_FAILURE; } /* loop to the next non null vector */ k = 0; for (i=0, x=-1; i<uvlinfo->width && k<=shapeindex; ++i, ++x) { for (j=0, y=-1; j<uvlinfo->height && k<=shapeindex; ++j, ++k, ++y) { if (uvlinfo->u[i][j] == 0 && uvlinfo->v[i][j] == 0) --k; } } point.x = Pix2Georef(x, 0, uvlinfo->width-1, uvlinfo->extent.minx, uvlinfo->extent.maxx, MS_FALSE); point.y = Pix2Georef(y, 0, uvlinfo->height-1, uvlinfo->extent.miny, uvlinfo->extent.maxy, MS_TRUE); if (layer->debug == 5) msDebug("msUVRASTERLayerWhichShapes(): shapeindex: %ld, x: %g, y: %g\n", shapeindex, point.x, point.y); #ifdef USE_POINT_Z_M point.m = 0.0; #endif shape->type = MS_SHAPE_POINT; line.numpoints = 1; line.point = &point; msAddLine( shape, &line ); msComputeBounds( shape ); shape->numvalues = layer->numitems; shape->values = msUVRASTERGetValues(layer, &uvlinfo->u[x][y], &uvlinfo->v[x][y]); return MS_SUCCESS; }
/* static pointObj get_metrics(pointObj *p, int position, rectObj rect, int ox, int oy, double angle, int buffer, shapeObj *poly) */ pointObj get_metrics(pointObj *p, int position, rectObj rect, int ox, int oy, double angle, int buffer, shapeObj *poly) { lineObj newline; pointObj newpoints[5]; pointObj rp; newline.numpoints=5; newline.point=newpoints; rp = get_metrics_line(p, position, rect, ox,oy, angle, buffer, &newline); if(poly) { msAddLine(poly,&newline); msComputeBounds(poly); } return rp; }
static shapeObj *msGEOSGeometry2Shape_multiline(GEOSGeom g) { int i, j; int numPoints, numLines; GEOSCoordSeq coords; GEOSGeom lineString; shapeObj *shape=NULL; lineObj line; if(!g) return NULL; numLines = GEOSGetNumGeometries(g); shape = (shapeObj *) malloc(sizeof(shapeObj)); msInitShape(shape); shape->type = MS_SHAPE_LINE; shape->geometry = (GEOSGeom) g; for(j=0; j<numLines; j++) { lineString = (GEOSGeom) GEOSGetGeometryN(g, j); numPoints = GEOSGetNumCoordinates(lineString); coords = (GEOSCoordSeq) GEOSGeom_getCoordSeq(lineString); line.point = (pointObj *) malloc(sizeof(pointObj)*numPoints); line.numpoints = numPoints; for(i=0; i<numPoints; i++) { GEOSCoordSeq_getX(coords, i, &(line.point[i].x)); GEOSCoordSeq_getY(coords, i, &(line.point[i].y)); /* GEOSCoordSeq_getZ(coords, i, &(line.point[i].z)); */ } msAddLineDirectly(shape, &line); } msComputeBounds(shape); return shape; }
/* * RFC48 implementation: * - transform the original shapeobj * - use the styleObj to render the transformed shapeobj */ int msDrawTransformedShape(mapObj *map, imageObj *image, shapeObj *shape, styleObj *style, double scalefactor) { int type = style->_geomtransform.type; int i,j,status = MS_SUCCESS; switch(type) { case MS_GEOMTRANSFORM_END: /*render point on last vertex only*/ for(j=0; j<shape->numlines; j++) { lineObj *line = &(shape->line[j]); pointObj *p = &(line->point[line->numpoints-1]); if(p->x<0||p->x>image->width||p->y<0||p->y>image->height) continue; if(style->autoangle==MS_TRUE && line->numpoints>1) { style->angle = calcOrientation(&(line->point[line->numpoints-2]),p); } status = msDrawMarkerSymbol(map,image,p,style,scalefactor); } break; case MS_GEOMTRANSFORM_START: /*render point on first vertex only*/ for(j=0; j<shape->numlines; j++) { lineObj *line = &(shape->line[j]); pointObj *p = &(line->point[0]); /*skip if outside image*/ if(p->x<0||p->x>image->width||p->y<0||p->y>image->height) continue; if(style->autoangle==MS_TRUE && line->numpoints>1) { style->angle = calcOrientation(p,&(line->point[1])); } status = msDrawMarkerSymbol(map,image,p,style,scalefactor); } break; case MS_GEOMTRANSFORM_VERTICES: for(j=0; j<shape->numlines; j++) { lineObj *line = &(shape->line[j]); for(i=1; i<line->numpoints-1; i++) { pointObj *p = &(line->point[i]); /*skip points outside image*/ if(p->x<0||p->x>image->width||p->y<0||p->y>image->height) continue; if(style->autoangle==MS_TRUE) { style->angle = calcMidAngle(&(line->point[i-1]),&(line->point[i]),&(line->point[i+1])); } status = msDrawMarkerSymbol(map,image,p,style,scalefactor); } } break; case MS_GEOMTRANSFORM_BBOX: { shapeObj bbox; lineObj bbox_line; pointObj bbox_points[5]; int padding = MS_MAX(style->width,style->size)+3; /* so clipped shape does not extent into image */ /*create a shapeObj representing the bounding box (clipped by the image size)*/ bbox.numlines = 1; bbox.line = &bbox_line; bbox.line->numpoints = 5; bbox.line->point = bbox_points; msComputeBounds(shape); bbox_points[0].x=bbox_points[4].x=bbox_points[1].x = (shape->bounds.minx < -padding) ? -padding : shape->bounds.minx; bbox_points[2].x=bbox_points[3].x = (shape->bounds.maxx > image->width+padding) ? image->width+padding : shape->bounds.maxx; bbox_points[0].y=bbox_points[4].y=bbox_points[3].y = (shape->bounds.miny < -padding) ? -padding : shape->bounds.miny; bbox_points[1].y=bbox_points[2].y = (shape->bounds.maxy > image->height+padding) ? image->height+padding : shape->bounds.maxy; status = msDrawShadeSymbol(map, image, &bbox, style, scalefactor); } break; case MS_GEOMTRANSFORM_CENTROID: { double unused; /*used by centroid function*/ pointObj centroid; if(MS_SUCCESS == msGetPolygonCentroid(shape,¢roid,&unused,&unused)) { status = msDrawMarkerSymbol(map,image,¢roid,style,scalefactor); } } break; case MS_GEOMTRANSFORM_EXPRESSION: { int status; shapeObj *tmpshp; parseObj p; p.shape = shape; /* set a few parser globals (hence the lock) */ p.expr = &(style->_geomtransform); if(p.expr->tokens == NULL) { /* this could happen if drawing originates from legend code (#5193) */ status = msTokenizeExpression(p.expr, NULL, NULL); if(status != MS_SUCCESS) { msSetError(MS_MISCERR, "Unable to tokenize expression.", "msDrawTransformedShape()"); return MS_FAILURE; } } p.expr->curtoken = p.expr->tokens; /* reset */ p.type = MS_PARSE_TYPE_SHAPE; status = yyparse(&p); if (status != 0) { msSetError(MS_PARSEERR, "Failed to process shape expression: %s", "msDrawTransformedShape", style->_geomtransform.string); return MS_FAILURE; } tmpshp = p.result.shpval; switch (tmpshp->type) { case MS_SHAPE_POINT: case MS_SHAPE_POLYGON: status = msDrawShadeSymbol(map, image, tmpshp, style, scalefactor); break; case MS_SHAPE_LINE: status = msDrawLineSymbol(map, image, tmpshp, style, scalefactor); break; } msFreeShape(tmpshp); msFree(tmpshp); } break; case MS_GEOMTRANSFORM_LABELPOINT: case MS_GEOMTRANSFORM_LABELPOLY: break; default: msSetError(MS_MISCERR, "unknown geomtransform", "msDrawTransformedShape()"); return MS_FAILURE; } return status; }
static int msProjectShapeLine(projectionObj *in, projectionObj *out, shapeObj *shape, int line_index) { int i; pointObj lastPoint, thisPoint, wrkPoint; lineObj *line = shape->line + line_index; lineObj *line_out = line; int valid_flag = 0; /* 1=true, -1=false, 0=unknown */ int numpoints_in = line->numpoints; int line_alloc = numpoints_in; int wrap_test; #ifdef USE_PROJ_FASTPATHS #define MAXEXTENT 20037508.34 #define M_PIby360 .0087266462599716479 #define MAXEXTENTby180 111319.4907777777777777777 #define p_x line->point[i].x #define p_y line->point[i].y if(in->wellknownprojection == wkp_lonlat && out->wellknownprojection == wkp_gmerc) { for( i = line->numpoints-1; i >= 0; i-- ) { p_x *= MAXEXTENTby180; p_y = log(tan((90 + p_y) * M_PIby360)) * MS_RAD_TO_DEG; p_y *= MAXEXTENTby180; if (p_x > MAXEXTENT) p_x = MAXEXTENT; if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; if (p_y > MAXEXTENT) p_y = MAXEXTENT; if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; } return MS_SUCCESS; } if(in->wellknownprojection == wkp_gmerc && out->wellknownprojection == wkp_lonlat) { for( i = line->numpoints-1; i >= 0; i-- ) { if (p_x > MAXEXTENT) p_x = MAXEXTENT; else if (p_x < -MAXEXTENT) p_x = -MAXEXTENT; if (p_y > MAXEXTENT) p_y = MAXEXTENT; else if (p_y < -MAXEXTENT) p_y = -MAXEXTENT; p_x = (p_x / MAXEXTENT) * 180; p_y = (p_y / MAXEXTENT) * 180; p_y = MS_RAD_TO_DEG * (2 * atan(exp(p_y * MS_DEG_TO_RAD)) - MS_PI2); } msComputeBounds( shape ); /* fixes bug 1586 */ return MS_SUCCESS; } #undef p_x #undef p_y #endif wrap_test = out != NULL && out->proj != NULL && pj_is_latlong(out->proj) && !pj_is_latlong(in->proj); line->numpoints = 0; memset( &lastPoint, 0, sizeof(lastPoint) ); /* -------------------------------------------------------------------- */ /* Loop over all input points in linestring. */ /* -------------------------------------------------------------------- */ for( i=0; i < numpoints_in; i++ ) { int ms_err; wrkPoint = thisPoint = line->point[i]; ms_err = msProjectPoint(in, out, &wrkPoint ); /* -------------------------------------------------------------------- */ /* Apply wrap logic. */ /* -------------------------------------------------------------------- */ if( wrap_test && i > 0 && ms_err != MS_FAILURE ) { double dist; pointObj pt1Geo; if( line_out->numpoints > 0 ) pt1Geo = line_out->point[line_out->numpoints-1]; else pt1Geo = wrkPoint; /* this is a cop out */ dist = wrkPoint.x - pt1Geo.x; if( fabs(dist) > 180.0 && msTestNeedWrap( thisPoint, lastPoint, pt1Geo, in, out ) ) { if( dist > 0.0 ) wrkPoint.x -= 360.0; else if( dist < 0.0 ) wrkPoint.x += 360.0; } } /* -------------------------------------------------------------------- */ /* Put result into output line with appropriate logic for */ /* failure breaking lines, etc. */ /* -------------------------------------------------------------------- */ if( ms_err == MS_FAILURE ) { /* We have started out invalid */ if( i == 0 ) { valid_flag = -1; } /* valid data has ended, we need to work out the horizon */ else if( valid_flag == 1 ) { pointObj startPoint, endPoint; startPoint = lastPoint; endPoint = thisPoint; if( msProjectSegment( in, out, &startPoint, &endPoint ) == MS_SUCCESS ) { line_out->point[line_out->numpoints++] = endPoint; } valid_flag = -1; } /* Still invalid ... */ else if( valid_flag == -1 ) { /* do nothing */ } } else { /* starting out valid. */ if( i == 0 ) { line_out->point[line_out->numpoints++] = wrkPoint; valid_flag = 1; } /* Still valid, nothing special */ else if( valid_flag == 1 ) { line_out->point[line_out->numpoints++] = wrkPoint; } /* we have come over the horizon, figure out where, start newline*/ else { pointObj startPoint, endPoint; startPoint = lastPoint; endPoint = thisPoint; if( msProjectSegment( in, out, &endPoint, &startPoint ) == MS_SUCCESS ) { lineObj newLine; /* force pre-allocation of lots of points room */ if( line_out->numpoints > 0 && shape->type == MS_SHAPE_LINE ) { newLine.numpoints = numpoints_in - i + 1; newLine.point = line->point; msAddLine( shape, &newLine ); /* new line is now lineout, but start without any points */ line_out = shape->line + shape->numlines-1; line_out->numpoints = 0; /* the shape->line array is realloc, refetch "line" */ line = shape->line + line_index; } else if( line_out == line && line->numpoints >= i-2 ) { newLine.numpoints = numpoints_in; newLine.point = line->point; msAddLine( shape, &newLine ); line = shape->line + line_index; line_out = shape->line + shape->numlines-1; line_out->numpoints = line->numpoints; line->numpoints = 0; /* * Now realloc this array large enough to hold all * the points we could possibly need to add. */ line_alloc = line_alloc * 2; line_out->point = (pointObj *) realloc(line_out->point, sizeof(pointObj) * line_alloc); } line_out->point[line_out->numpoints++] = startPoint; } line_out->point[line_out->numpoints++] = wrkPoint; valid_flag = 1; } } lastPoint = thisPoint; } /* -------------------------------------------------------------------- */ /* Make sure that polygons are closed, even if the trip over */ /* the horizon left them unclosed. */ /* -------------------------------------------------------------------- */ if( shape->type == MS_SHAPE_POLYGON && line_out->numpoints > 2 && (line_out->point[0].x != line_out->point[line_out->numpoints-1].x || line_out->point[0].y != line_out->point[line_out->numpoints-1].y) ) { /* make a copy because msAddPointToLine can realloc the array */ pointObj sFirstPoint = line_out->point[0]; msAddPointToLine( line_out, &sFirstPoint ); } return(MS_SUCCESS); }