/////////////////////////////////////////////////////////////////////////////// // 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); } } }
void SE_PositioningAlgorithms::Default(SE_ApplyContext* applyCtx, SE_RenderStyle* rstyle) { // the style needs to contain at least one primitive SE_RenderPrimitiveList& prims = rstyle->symbol; if (prims.size() == 0) return; SE_Renderer* se_renderer = applyCtx->renderer; LineBuffer* geometry = applyCtx->geometry; SE_Matrix& xform = *applyCtx->xform; double cx = 0.0; double cy = 0.0; double offsetX = 0.0; double offsetY = 0.0; double angleRad = 0.0; switch (rstyle->type) { case SE_RenderStyle_Point: { SE_RenderPointStyle* rpStyle = (SE_RenderPointStyle*)rstyle; // get the feature centroid (no angle for point centroids) geometry->Centroid(LineBuffer::ctPoint, &cx, &cy, NULL); // account for the point usage angle control and offset angleRad = rpStyle->angleRad; offsetX = rpStyle->offset[0]; offsetY = rpStyle->offset[1]; break; } case SE_RenderStyle_Line: { SE_RenderLineStyle* rlStyle = (SE_RenderLineStyle*)rstyle; // get the feature centroid and angle double fAngleRad; geometry->Centroid(LineBuffer::ctLine, &cx, &cy, &fAngleRad); // account for the angle control angleRad = rlStyle->angleRad; if (rlStyle->angleControl == SE_AngleControl_FromGeometry) angleRad += fAngleRad; break; } case SE_RenderStyle_Area: { SE_RenderAreaStyle* raStyle = (SE_RenderAreaStyle*)rstyle; // get the feature centroid (no angle for area centroids) geometry->Centroid(LineBuffer::ctArea, &cx, &cy, NULL); // account for the angle control angleRad = raStyle->angleRad; break; } } // don't add a label if we can't compute the centroid if (_isnan(cx) || _isnan(cy)) return; // need to convert centroid to screen units se_renderer->WorldToScreenPoint(cx, cy, cx, cy); // also account for any viewport rotation angleRad += se_renderer->GetWorldToScreenRotation(); // see StylizationEngine::Stylize for a detailed explanation of these transforms bool yUp = se_renderer->YPointsUp(); SE_Matrix xformLabel; xformLabel.translate(offsetX, offsetY); xformLabel.rotate(yUp? angleRad : -angleRad); xformLabel.premultiply(xform); xformLabel.translate(cx, cy); se_renderer->AddLabel(geometry, rstyle, xformLabel, angleRad); }