/////////////////////////////////////////////////////////////////////////////// // Called when applying an area style on a feature geometry. Area styles can // can only be applied to polygon feature geometry types. void SE_Renderer::ProcessArea(SE_ApplyContext* ctx, SE_RenderAreaStyle* style) { // the feature geometry we're applying the style on... LineBuffer* featGeom = ctx->geometry; // can't apply an area style to point and linestring geometry types switch (featGeom->geom_type()) { case GeometryType_Point: case GeometryType_MultiPoint: case GeometryType_LineString: case GeometryType_MultiLineString: case GeometryType_CurveString: case GeometryType_MultiCurveString: return; } SE_Matrix w2s; GetWorldToScreenTransform(w2s); //-------------------------------------------------------------- // special code to handle simple solid fill styles //-------------------------------------------------------------- if (style->solidFill) { // just draw it and bail out of the layout function SE_RenderPolygon* rp = (SE_RenderPolygon*)style->symbol[0]; if (m_bSelectionMode) DrawScreenPolygon(featGeom, &w2s, m_selFillColor); else DrawScreenPolygon(featGeom, &w2s, rp->fill); return; } // transform the feature geometry to rendering space LineBuffer* xfgeom = LineBufferPool::NewLineBuffer(m_pPool, featGeom->point_count()); std::auto_ptr<LineBuffer> spLB(xfgeom); *xfgeom = *featGeom; int size = featGeom->point_count(); for (int i=0; i<size; ++i) w2s.transform(xfgeom->x_coord(i), xfgeom->y_coord(i)); // recompute the bounds RS_Bounds& bounds = const_cast<RS_Bounds&>(xfgeom->bounds()); bounds.minx = bounds.miny = bounds.minz = +DBL_MAX; bounds.maxx = bounds.maxy = bounds.maxz = -DBL_MAX; xfgeom->ComputeBounds(bounds); // account for any viewport rotation SE_AreaPositioning ap(xfgeom, style, GetWorldToScreenRotation()); double baserot = ap.PatternRotation(); SE_Matrix xform; SE_Matrix xformbase = *ctx->xform; xformbase.rotate(baserot); for (const Point2D* pos = ap.NextLocation(); pos != NULL; pos = ap.NextLocation()) { xform = xformbase; xform.translate(pos->x, pos->y); DrawSymbol(style->symbol, xform, baserot, style->addToExclusionRegion); } LineBufferPool::FreeLineBuffer(m_pPool, spLB.release()); }
/////////////////////////////////////////////////////////////////////////////// // Called when applying a point style on a feature geometry. Point styles can // be applied to all feature geometry types. void SE_Renderer::ProcessPoint(SE_ApplyContext* ctx, SE_RenderPointStyle* style, RS_Bounds* bounds) { // the feature geometry we're applying the style on... LineBuffer* featGeom = ctx->geometry; double angleRad = 0.0; if (style->angleControl == SE_AngleControl_FromGeometry) { switch (featGeom->geom_type()) { case GeometryType_LineString: case GeometryType_MultiLineString: case GeometryType_Polygon: case GeometryType_MultiPolygon: { double x0, y0; featGeom->Centroid(LineBuffer::ctLine, &x0, &y0, &angleRad); break; } } } angleRad += style->angleRad; // also account for any viewport rotation angleRad += GetWorldToScreenRotation(); SE_Matrix xform; bool yUp = YPointsUp(); // see StylizationEngine::Stylize for a detailed explanation of these transforms SE_Matrix xformbase; xformbase.translate(style->offset[0], style->offset[1]); xformbase.rotate(yUp? angleRad : -angleRad); xformbase.premultiply(*ctx->xform); // render the points for (int i=0; i<featGeom->point_count(); ++i) { double x, y; featGeom->get_point(i, x, y); // transform to screen space - feature geometry is in [the original] mapping space WorldToScreenPoint(x, y, x, y); xform = xformbase; xform.translate(x, y); if (style->drawLast) AddLabel(featGeom, style, xform, angleRad); else DrawSymbol(style->symbol, xform, angleRad, style->addToExclusionRegion); } if (bounds) { // get the symbol bounds after applying the transforms bounds->minx = bounds->miny = +DBL_MAX; bounds->maxx = bounds->maxy = -DBL_MAX; for (int i=0; i<4; ++i) { RS_F_Point xfpt; xformbase.transform(style->bounds[i].x, style->bounds[i].y, xfpt.x, xfpt.y); bounds->add_point(xfpt); } } }