void agg_renderer<T>::process(point_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
    
    boost::optional<mapnik::marker_ptr> marker;
    if ( !filename.empty() )
    {
        marker = marker_cache::instance()->find(filename, true);
    }
    else
    {
        marker.reset(boost::make_shared<mapnik::marker>());
    }

    if (marker)
    {
        for (unsigned i=0; i<feature.num_geometries(); ++i)
        {
            geometry_type const& geom = feature.get_geometry(i);
            double x;
            double y;
            double z=0;
            if (sym.get_point_placement() == CENTROID_POINT_PLACEMENT)
                geom.label_position(&x, &y);
            else
                geom.label_interior_position(&x, &y);

            prj_trans.backward(x,y,z);
            t_.forward(&x,&y);

            int w = (*marker)->width();
            int h = (*marker)->height();

            int px = int(floor(x - 0.5 * w));
            int py = int(floor(y - 0.5 * h));
            box2d<double> label_ext (px, py, px + w, py + h);
            if (sym.get_allow_overlap() ||
                detector_.has_placement(label_ext))
            {
                agg::trans_affine tr;
                boost::array<double,6> const& m = sym.get_transform();
                tr.load_from(&m[0]);

                render_marker(px,py,**marker,tr, sym.get_opacity());

                if (!sym.get_ignore_placement())
                    detector_.insert(label_ext);
                metawriter_with_properties writer = sym.get_metawriter();
                if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
            }
        }
    }

}
Exemplo n.º 2
0
 bool pass(Feature const& feature)
 {
     for (unsigned i=0;i<feature.num_geometries();++i)
     {
         geometry_type const& geom = feature.get_geometry(i);
         if (geom.hit_test(x_,y_,tol_))
             return true;
     }
     return false;
 }
void  agg_renderer<T>::process(line_pattern_symbolizer const& sym,
                               Feature const& feature,
                               proj_transform const& prj_trans)
{
    typedef  coord_transform2<CoordTransform,geometry_type> path_type;
    typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
    typedef agg::renderer_base<agg::pixfmt_rgba32_plain> renderer_base;
    typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
    typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;

    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32_plain pixf(buf);
    
    std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);

    boost::optional<marker_ptr> mark = marker_cache::instance()->find(filename,true);
    if (!mark || !(*mark)->is_bitmap()) return;

    boost::optional<image_ptr> pat = (*mark)->get_bitmap_data();

    if (!pat) return;
      
    renderer_base ren_base(pixf);
    agg::pattern_filter_bilinear_rgba8 filter;
    pattern_source source(*(*pat));
    pattern_type pattern (filter,source);
    renderer_type ren(ren_base, pattern);
    ren.clip_box(0,0,width_,height_);
    rasterizer_type ras(ren);
    metawriter_with_properties writer = sym.get_metawriter();
    for (unsigned i=0;i<feature.num_geometries();++i)
    {
        geometry_type const& geom = feature.get_geometry(i);
        if (geom.num_points() > 1)
        {
            path_type path(t_,geom,prj_trans);
            ras.add_path(path);
            if (writer.first) writer.first->add_line(path, feature, t_, writer.second);
        }
    }
}
Exemplo n.º 4
0
void agg_renderer<T>::process(line_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
    typedef coord_transform2<CoordTransform,geometry_type> path_type;

    stroke const& stroke_ = sym.get_stroke();
    color const& col = stroke_.get_color();
    unsigned r=col.red();
    unsigned g=col.green();
    unsigned b=col.blue();
    unsigned a=col.alpha();
    
    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32_plain pixf(buf);
    
    if (sym.get_rasterizer() == RASTERIZER_FAST)
    {
        typedef agg::renderer_outline_aa<ren_base> renderer_type;
        typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;

        agg::line_profile_aa profile;
        //agg::line_profile_aa profile(stroke_.get_width() * scale_factor_, agg::gamma_none());
        profile.width(stroke_.get_width() * scale_factor_);
        ren_base base_ren(pixf);
        renderer_type ren(base_ren, profile);
        ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
        //ren.clip_box(0,0,width_,height_);
        rasterizer_type ras(ren);
        ras.line_join(agg::outline_miter_accurate_join);
        ras.round_cap(true);
   
        for (unsigned i=0;i<feature.num_geometries();++i)
        {
            geometry_type const& geom = feature.get_geometry(i);
            if (geom.num_points() > 1)
            {
                path_type path(t_,geom,prj_trans);
                ras.add_path(path);
            }
        }
    }
    else
    {
        typedef agg::renderer_scanline_aa_solid<ren_base> renderer;

        agg::scanline_p8 sl;
    
        ren_base renb(pixf);
        renderer ren(renb);
        ras_ptr->reset();
        switch (stroke_.get_gamma_method())
        {
            case GAMMA_POWER:
                ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma()));
                break;
            case GAMMA_LINEAR:
                ras_ptr->gamma(agg::gamma_linear(0.0, stroke_.get_gamma()));
                break;
            case GAMMA_NONE:
                ras_ptr->gamma(agg::gamma_none());
                break;
            case GAMMA_THRESHOLD:
                ras_ptr->gamma(agg::gamma_threshold(stroke_.get_gamma()));
                break;
            case GAMMA_MULTIPLY:
                ras_ptr->gamma(agg::gamma_multiply(stroke_.get_gamma()));
                break;
            default:
                ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma()));
        }
        
        metawriter_with_properties writer = sym.get_metawriter();
        for (unsigned i=0;i<feature.num_geometries();++i)
        {
            geometry_type const& geom = feature.get_geometry(i);
            if (geom.num_points() > 1)
            {
                path_type path(t_,geom,prj_trans);
    
                if (stroke_.has_dash())
                {
                    agg::conv_dash<path_type> dash(path);
                    dash_array const& d = stroke_.get_dash_array();
                    dash_array::const_iterator itr = d.begin();
                    dash_array::const_iterator end = d.end();
                    for (;itr != end;++itr)
                    {
                        dash.add_dash(itr->first * scale_factor_, 
                                      itr->second * scale_factor_);
                    }
    
                    agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);
    
                    line_join_e join=stroke_.get_line_join();
                    if ( join == MITER_JOIN)
                        stroke.generator().line_join(agg::miter_join);
                    else if( join == MITER_REVERT_JOIN)
                        stroke.generator().line_join(agg::miter_join);
                    else if( join == ROUND_JOIN)
                        stroke.generator().line_join(agg::round_join);
                    else
                        stroke.generator().line_join(agg::bevel_join);
    
                    line_cap_e cap=stroke_.get_line_cap();
                    if (cap == BUTT_CAP)
                        stroke.generator().line_cap(agg::butt_cap);
                    else if (cap == SQUARE_CAP)
                        stroke.generator().line_cap(agg::square_cap);
                    else
                        stroke.generator().line_cap(agg::round_cap);
    
                    stroke.generator().miter_limit(4.0);
                    stroke.generator().width(stroke_.get_width() * scale_factor_);
                    ras_ptr->add_path(stroke);
    
                }
                else
                {
                    agg::conv_stroke<path_type>  stroke(path);
                    line_join_e join=stroke_.get_line_join();
                    if ( join == MITER_JOIN)
                        stroke.generator().line_join(agg::miter_join);
                    else if( join == MITER_REVERT_JOIN)
                        stroke.generator().line_join(agg::miter_join);
                    else if( join == ROUND_JOIN)
                        stroke.generator().line_join(agg::round_join);
                    else
                        stroke.generator().line_join(agg::bevel_join);
    
                    line_cap_e cap=stroke_.get_line_cap();
                    if (cap == BUTT_CAP)
                        stroke.generator().line_cap(agg::butt_cap);
                    else if (cap == SQUARE_CAP)
                        stroke.generator().line_cap(agg::square_cap);
                    else
                        stroke.generator().line_cap(agg::round_cap);
    
                    stroke.generator().miter_limit(4.0);
                    stroke.generator().width(stroke_.get_width() * scale_factor_);
                    ras_ptr->add_path(stroke);
                    if (writer.first) writer.first->add_line(path, feature, t_, writer.second);
                }
            }
        }
        ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
        agg::render_scanlines(*ras_ptr, sl, ren);    
    }
}
void grid_renderer<T>::process(line_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef coord_transform2<CoordTransform,geometry_type> path_type;
    typedef agg::renderer_base<mapnik::pixfmt_gray16> ren_base;
    typedef agg::renderer_scanline_bin_solid<ren_base> renderer;
    agg::scanline_bin sl;

    grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_);
    mapnik::pixfmt_gray16 pixf(buf);

    ren_base renb(pixf);
    renderer ren(renb);

    ras_ptr->reset();

    stroke const&  stroke_ = sym.get_stroke();

    for (unsigned i=0;i<feature.num_geometries();++i)
    {
        geometry_type const& geom = feature.get_geometry(i);
        if (geom.num_points() > 1)
        {
            path_type path(t_,geom,prj_trans);

            if (stroke_.has_dash())
            {
                agg::conv_dash<path_type> dash(path);
                dash_array const& d = stroke_.get_dash_array();
                dash_array::const_iterator itr = d.begin();
                dash_array::const_iterator end = d.end();
                for (;itr != end;++itr)
                {
                    dash.add_dash(itr->first * scale_factor_, 
                                  itr->second * scale_factor_);
                }

                agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);

                line_join_e join=stroke_.get_line_join();
                if ( join == MITER_JOIN)
                    stroke.generator().line_join(agg::miter_join);
                else if( join == MITER_REVERT_JOIN)
                    stroke.generator().line_join(agg::miter_join);
                else if( join == ROUND_JOIN)
                    stroke.generator().line_join(agg::round_join);
                else
                    stroke.generator().line_join(agg::bevel_join);

                line_cap_e cap=stroke_.get_line_cap();
                if (cap == BUTT_CAP)
                    stroke.generator().line_cap(agg::butt_cap);
                else if (cap == SQUARE_CAP)
                    stroke.generator().line_cap(agg::square_cap);
                else
                    stroke.generator().line_cap(agg::round_cap);

                stroke.generator().miter_limit(4.0);
                stroke.generator().width(stroke_.get_width() * scale_factor_);
                
                ras_ptr->add_path(stroke);

            }
            else
            {
                agg::conv_stroke<path_type>  stroke(path);
                line_join_e join=stroke_.get_line_join();
                if ( join == MITER_JOIN)
                    stroke.generator().line_join(agg::miter_join);
                else if( join == MITER_REVERT_JOIN)
                    stroke.generator().line_join(agg::miter_join);
                else if( join == ROUND_JOIN)
                    stroke.generator().line_join(agg::round_join);
                else
                    stroke.generator().line_join(agg::bevel_join);

                line_cap_e cap=stroke_.get_line_cap();
                if (cap == BUTT_CAP)
                    stroke.generator().line_cap(agg::butt_cap);
                else if (cap == SQUARE_CAP)
                    stroke.generator().line_cap(agg::square_cap);
                else
                    stroke.generator().line_cap(agg::round_cap);

                stroke.generator().miter_limit(4.0);
                stroke.generator().width(stroke_.get_width() * scale_factor_);
                ras_ptr->add_path(stroke);
            }
        }
    }

    // render id
    ren.color(mapnik::gray16(feature.id()));
    agg::render_scanlines(*ras_ptr, sl, ren);

    // add feature properties to grid cache
    pixmap_.add_feature(feature);

}
void agg_renderer<T>::process(building_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef  coord_transform2<CoordTransform,geometry_type> path_type;
    typedef  coord_transform3<CoordTransform,geometry_type> path_type_roof;
    typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
    typedef agg::renderer_scanline_aa_solid<ren_base> renderer;

    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32_plain pixf(buf);
    ren_base renb(pixf);

    color const& fill_  = sym.get_fill();
    unsigned r=fill_.red();
    unsigned g=fill_.green();
    unsigned b=fill_.blue();
    unsigned a=fill_.alpha();
    renderer ren(renb);
    agg::scanline_u8 sl;

    ras_ptr->reset();
    ras_ptr->gamma(agg::gamma_linear());
    
    double height = 0.0;
    expression_ptr height_expr = sym.height();
    if (height_expr)
    {
        value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr);
        height = result.to_double() * scale_factor_;
    }
    
    for (unsigned i=0;i<feature.num_geometries();++i)
    {
        geometry_type const& geom = feature.get_geometry(i);
        if (geom.num_points() > 2)
        {
            boost::scoped_ptr<geometry_type> frame(new geometry_type(LineString));
            boost::scoped_ptr<geometry_type> roof(new geometry_type(Polygon));
            std::deque<segment_t> face_segments;
            double x0(0);
            double y0(0);
            unsigned cm = geom.vertex(&x0,&y0);
            for (unsigned j=1;j<geom.num_points();++j)
            {
                double x(0);
                double y(0);
                cm = geom.vertex(&x,&y);
                if (cm == SEG_MOVETO)
                {
                    frame->move_to(x,y);
                }
                else if (cm == SEG_LINETO)
                {
                    frame->line_to(x,y);
                    face_segments.push_back(segment_t(x0,y0,x,y));
                }
                
                x0 = x;
                y0 = y;
            }
            std::sort(face_segments.begin(),face_segments.end(), y_order);
            std::deque<segment_t>::const_iterator itr=face_segments.begin();
            for (;itr!=face_segments.end();++itr)
            {
                boost::scoped_ptr<geometry_type> faces(new geometry_type(Polygon));
                faces->move_to(itr->get<0>(),itr->get<1>());
                faces->line_to(itr->get<2>(),itr->get<3>());
                faces->line_to(itr->get<2>(),itr->get<3>() + height);
                faces->line_to(itr->get<0>(),itr->get<1>() + height);

                path_type faces_path (t_,*faces,prj_trans);
                ras_ptr->add_path(faces_path);
                ren.color(agg::rgba8(int(r*0.8), int(g*0.8), int(b*0.8), int(a * sym.get_opacity())));
                agg::render_scanlines(*ras_ptr, sl, ren);
                ras_ptr->reset();

                frame->move_to(itr->get<0>(),itr->get<1>());
                frame->line_to(itr->get<0>(),itr->get<1>()+height);
            }
            geom.rewind(0);
            
            for (unsigned j=0;j<geom.num_points();++j)
            {
                double x,y;
                unsigned cm = geom.vertex(&x,&y);
                if (cm == SEG_MOVETO)
                {
                    frame->move_to(x,y+height);
                    roof->move_to(x,y+height);
                }
                else if (cm == SEG_LINETO)
                {
                    frame->line_to(x,y+height);
                    roof->line_to(x,y+height);
                }
            }
            geom.rewind(0);
            
            path_type path(t_,*frame,prj_trans);
            agg::conv_stroke<path_type> stroke(path);
            ras_ptr->add_path(stroke);
            ren.color(agg::rgba8(int(r*0.8), int(g*0.8), int(b*0.8), int(255 * sym.get_opacity())));
            agg::render_scanlines(*ras_ptr, sl, ren);
            ras_ptr->reset();

            path_type roof_path (t_,*roof,prj_trans);
            ras_ptr->add_path(roof_path);
            ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
            agg::render_scanlines(*ras_ptr, sl, ren);
        }
    }
}
Exemplo n.º 7
0
void agg_renderer<T>::process(point_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef agg::pixfmt_rgba32 pixfmt;
    typedef agg::renderer_base<pixfmt> renderer_base;
    typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
    
    double x;
    double y;
    double z=0;
    
    std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
    boost::optional<mapnik::image_ptr> data;
    
    if (is_svg(filename))
    {
        // SVG  
        using namespace mapnik::svg;
        boost::optional<path_ptr> marker;
        ras_ptr->reset();
        ras_ptr->gamma(agg::gamma_linear());
        agg::scanline_u8 sl;
        agg::rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_ * 4);
        pixfmt pixf(buf);
        renderer_base renb(pixf);
        renderer_solid ren(renb);
        box2d<double> extent;
        
        marker = marker_cache::instance()->find(filename, true);

        if (marker && *marker)
        {
            
            box2d<double> const& bbox = (*marker)->bounding_box();
            double x1 = bbox.minx();
            double y1 = bbox.miny();
            double x2 = bbox.maxx();
            double y2 = bbox.maxy();

            vertex_stl_adapter<svg_path_storage> stl_storage((*marker)->source());
            svg_path_adapter svg_path(stl_storage);
            svg_renderer<svg_path_adapter, 
                         agg::pod_bvector<path_attributes> > svg_renderer(svg_path,
                                                                          (*marker)->attributes());
            
            for (unsigned i=0; i<feature.num_geometries(); ++i)
            {
                geometry2d const& geom = feature.get_geometry(i);  
                geom.label_position(&x,&y);
                prj_trans.backward(x,y,z);
                t_.forward(&x,&y);
                
                agg::trans_affine tr;
                boost::array<double,6> const& m = sym.get_transform();
                tr.load_from(&m[0]);
                tr *= agg::trans_affine_scaling(scale_factor_);
                tr *= agg::trans_affine_translation(x, y);
                
                tr.transform(&x1,&y1);
                tr.transform(&x2,&y2);
                
                extent.init(x1,y1,x2,y2);
                if (sym.get_allow_overlap() ||
                    detector_.has_placement(extent))
                {
                    svg_renderer.render(*ras_ptr, sl, ren, tr, renb.clip_box(), sym.get_opacity());
                    detector_.insert(extent);
                    metawriter_with_properties writer = sym.get_metawriter();
                    if (writer.first)
                    {
                        writer.first->add_box(extent, feature, t_, writer.second);
                    }
                }
            }   
        }
    }
    else
    {
        if ( filename.empty() )
        {
            // default OGC 4x4 black square
            data = boost::optional<mapnik::image_ptr>(new image_data_32(4,4));
            (*data)->set(0xff000000);
        }
        else
        {
            data = mapnik::image_cache::instance()->find(filename,true);    
        }

        if ( data )
        {
            for (unsigned i=0; i<feature.num_geometries(); ++i)
            {
                geometry2d const& geom = feature.get_geometry(i);
                
                geom.label_position(&x,&y);
                prj_trans.backward(x,y,z);
                t_.forward(&x,&y);
                int w = (*data)->width();
                int h = (*data)->height();
                int px = int(floor(x - 0.5 * w));
                int py = int(floor(y - 0.5 * h));
                box2d<double> label_ext (px, py, px + w, py + h);
                if (sym.get_allow_overlap() ||
                    detector_.has_placement(label_ext))
                {
                    pixmap_.set_rectangle_alpha2(*(*data), px, py, sym.get_opacity());
                    detector_.insert(label_ext);
                    metawriter_with_properties writer = sym.get_metawriter();
                    if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
                }
            }
        }
    }
}
void agg_renderer<T>::process(line_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
    typedef coord_transform2<CoordTransform,geometry_type> path_type;
    typedef agg::renderer_outline_aa<ren_base> renderer_oaa;
    typedef agg::rasterizer_outline_aa<renderer_oaa> rasterizer_outline_aa;
    typedef agg::renderer_scanline_aa_solid<ren_base> renderer;

    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32_plain pixf(buf);

    ren_base renb(pixf);
    stroke const&  stroke_ = sym.get_stroke();
    color const& col = stroke_.get_color();
    unsigned r=col.red();
    unsigned g=col.green();
    unsigned b=col.blue();
    unsigned a=col.alpha();
    renderer ren(renb);
    ras_ptr->reset();
    ras_ptr->gamma(agg::gamma_linear());
    
    agg::scanline_p8 sl;
    metawriter_with_properties writer = sym.get_metawriter();
    for (unsigned i=0;i<feature.num_geometries();++i)
    {
        geometry_type const& geom = feature.get_geometry(i);
        if (geom.num_points() > 1)
        {
            path_type path(t_,geom,prj_trans);

            if (stroke_.has_dash())
            {
                agg::conv_dash<path_type> dash(path);
                dash_array const& d = stroke_.get_dash_array();
                dash_array::const_iterator itr = d.begin();
                dash_array::const_iterator end = d.end();
                for (;itr != end;++itr)
                {
                    dash.add_dash(itr->first * scale_factor_, 
                                  itr->second * scale_factor_);
                }

                agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);

                line_join_e join=stroke_.get_line_join();
                if ( join == MITER_JOIN)
                    stroke.generator().line_join(agg::miter_join);
                else if( join == MITER_REVERT_JOIN)
                    stroke.generator().line_join(agg::miter_join);
                else if( join == ROUND_JOIN)
                    stroke.generator().line_join(agg::round_join);
                else
                    stroke.generator().line_join(agg::bevel_join);

                line_cap_e cap=stroke_.get_line_cap();
                if (cap == BUTT_CAP)
                    stroke.generator().line_cap(agg::butt_cap);
                else if (cap == SQUARE_CAP)
                    stroke.generator().line_cap(agg::square_cap);
                else
                    stroke.generator().line_cap(agg::round_cap);

                stroke.generator().miter_limit(4.0);
                stroke.generator().width(stroke_.get_width() * scale_factor_);
                
                ras_ptr->add_path(stroke);

            }
            else
            {
                agg::conv_stroke<path_type>  stroke(path);
                line_join_e join=stroke_.get_line_join();
                if ( join == MITER_JOIN)
                    stroke.generator().line_join(agg::miter_join);
                else if( join == MITER_REVERT_JOIN)
                    stroke.generator().line_join(agg::miter_join);
                else if( join == ROUND_JOIN)
                    stroke.generator().line_join(agg::round_join);
                else
                    stroke.generator().line_join(agg::bevel_join);

                line_cap_e cap=stroke_.get_line_cap();
                if (cap == BUTT_CAP)
                    stroke.generator().line_cap(agg::butt_cap);
                else if (cap == SQUARE_CAP)
                    stroke.generator().line_cap(agg::square_cap);
                else
                    stroke.generator().line_cap(agg::round_cap);

                stroke.generator().miter_limit(4.0);
                stroke.generator().width(stroke_.get_width() * scale_factor_);
                ras_ptr->add_path(stroke);
                if (writer.first) writer.first->add_line(path, feature, t_, writer.second);
            }
        }
    }
    ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
    agg::render_scanlines(*ras_ptr, sl, ren);
}
Exemplo n.º 9
0
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef coord_transform2<CoordTransform,geometry_type> path_type;
    typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
    typedef agg::wrap_mode_repeat wrap_x_type;
    typedef agg::wrap_mode_repeat wrap_y_type;
    typedef agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32,
        agg::row_accessor<agg::int8u>, agg::pixel32_type> rendering_buffer;
    typedef agg::image_accessor_wrap<rendering_buffer,
        wrap_x_type,
        wrap_y_type> img_source_type;

    typedef agg::span_pattern_rgba<img_source_type> span_gen_type;

    typedef agg::renderer_scanline_aa<ren_base,
        agg::span_allocator<agg::rgba8>,
        span_gen_type> renderer_type;


    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32_plain pixf(buf);
    ren_base renb(pixf);
    
    agg::scanline_u8 sl;
    ras_ptr->reset();
    ras_ptr->gamma(agg::gamma_linear(0.0, sym.get_gamma()));

    std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
    boost::optional<mapnik::marker_ptr> marker;
    if ( !filename.empty() )
    {
        marker = marker_cache::instance()->find(filename, true);
    }
    else
    {
        std::clog << "### Warning: file not found: " << filename << "\n";
    }

    if (!marker || !(*marker)->is_bitmap()) return;
    

    boost::optional<image_ptr> pat = (*marker)->get_bitmap_data();

    if (!pat) return;
    
    unsigned w=(*pat)->width();
    unsigned h=(*pat)->height();
    agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)(*pat)->getBytes(),w,h,w*4);
    agg::span_allocator<agg::rgba8> sa;
    agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32,
        agg::row_accessor<agg::int8u>, agg::pixel32_type> pixf_pattern(pattern_rbuf);
    img_source_type img_src(pixf_pattern);
    
    unsigned num_geometries = feature.num_geometries();

    pattern_alignment_e align = sym.get_alignment();
    unsigned offset_x=0;
    unsigned offset_y=0;
    
    if (align == LOCAL_ALIGNMENT)
    {
        double x0=0,y0=0;
        if (num_geometries>0)
        {
            path_type path(t_,feature.get_geometry(0),prj_trans);
            path.vertex(&x0,&y0);
        }
        offset_x = unsigned(width_-x0);
        offset_y = unsigned(height_-y0);    
    }
    
    span_gen_type sg(img_src, offset_x, offset_y);
    renderer_type rp(renb,sa, sg);
    metawriter_with_properties writer = sym.get_metawriter();
    for (unsigned i=0;i<num_geometries;++i)
    {
        geometry_type const& geom = feature.get_geometry(i);
        if (geom.num_points() > 2)
        {
            path_type path(t_,geom,prj_trans);
            ras_ptr->add_path(path);
            if (writer.first) writer.first->add_polygon(path, feature, t_, writer.second);
        }
    }
    agg::render_scanlines(*ras_ptr, sl, rp);
}
Exemplo n.º 10
0
void grid_renderer<T>::process(text_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef  coord_transform2<CoordTransform,geometry_type> path_type;

    bool placement_found = false;
    text_placement_info_ptr placement_options = sym.get_placement_options()->get_placement_info();
    while (!placement_found && placement_options->next())
    {
        expression_ptr name_expr = sym.get_name();
        if (!name_expr) return;
        value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*name_expr);
        UnicodeString text = result.to_unicode();

        if ( sym.get_text_transform() == UPPERCASE)
        {
            text = text.toUpper();
        }
        else if ( sym.get_text_transform() == LOWERCASE)
        {
            text = text.toLower();
        }
        else if ( sym.get_text_transform() == CAPITALIZE)
        {
            text = text.toTitle(NULL);
        }

        if ( text.length() <= 0 ) continue;
        color const& fill = sym.get_fill();

        face_set_ptr faces;

        if (sym.get_fontset().size() > 0)
        {
            faces = font_manager_.get_face_set(sym.get_fontset());
        }
        else
        {
            faces = font_manager_.get_face_set(sym.get_face_name());
        }

        stroker_ptr strk = font_manager_.get_stroker();
        if (!(faces->size() > 0 && strk))
        {
            throw config_error("Unable to find specified font face '" + sym.get_face_name() + "'");
        }
        text_renderer<T> ren(pixmap_, faces, *strk);
        ren.set_pixel_size(placement_options->text_size * (scale_factor_ * (1.0/pixmap_.get_resolution())));
        ren.set_fill(fill);
        ren.set_halo_fill(sym.get_halo_fill());
        ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
        ren.set_opacity(sym.get_text_opacity());

        // /pixmap_.get_resolution() ?
        box2d<double> dims(0,0,width_,height_);
        placement_finder<label_collision_detector4> finder(detector_,dims);

        string_info info(text);

        faces->get_string_info(info);
        unsigned num_geom = feature.num_geometries();
        for (unsigned i=0; i<num_geom; ++i)
        {
            geometry_type const& geom = feature.get_geometry(i);
            if (geom.num_points() == 0) continue; // don't bother with empty geometries
            while (!placement_found && placement_options->next_position_only())
            {
                placement text_placement(info, sym, scale_factor_);
                text_placement.avoid_edges = sym.get_avoid_edges();
                if (sym.get_label_placement() == POINT_PLACEMENT ||
                        sym.get_label_placement() == INTERIOR_PLACEMENT)
                {
                    double label_x, label_y, z=0.0;
                    if (sym.get_label_placement() == POINT_PLACEMENT)
                        geom.label_position(&label_x, &label_y);
                    else
                        geom.label_interior_position(&label_x, &label_y);
                    prj_trans.backward(label_x,label_y, z);
                    t_.forward(&label_x,&label_y);

                    double angle = 0.0;
                    expression_ptr angle_expr = sym.get_orientation();
                    if (angle_expr)
                    {
                        // apply rotation
                        value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*angle_expr);
                        angle = result.to_double();
                    }

                    finder.find_point_placement(text_placement, placement_options,
                                                label_x, label_y,
                                                angle, sym.get_line_spacing(),
                                                sym.get_character_spacing());

                    finder.update_detector(text_placement);
                }
                else if ( geom.num_points() > 1 && sym.get_label_placement() == LINE_PLACEMENT)
                {
                    path_type path(t_,geom,prj_trans);
                    finder.find_line_placements<path_type>(text_placement, placement_options, path);
                }

                if (!text_placement.placements.size()) continue;
                placement_found = true;

                for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ii)
                {
                    double x = text_placement.placements[ii].starting_x;
                    double y = text_placement.placements[ii].starting_y;
                    ren.prepare_glyphs(&text_placement.placements[ii]);
                    ren.render_id(feature.id(),x,y,2);
                }
            }
        }
    }
    if (placement_found)
        pixmap_.add_feature(feature);
}
void  agg_renderer<T>::process(shield_symbolizer const& sym,
                               Feature const& feature,
                               proj_transform const& prj_trans)
{
    typedef  coord_transform2<CoordTransform,geometry_type> path_type;


    text_placement_info_ptr placement_options = sym.get_placement_options()->get_placement_info();
    placement_options->next();
    placement_options->next_position_only();

    UnicodeString text;
    if( sym.get_no_text() )
        text = UnicodeString( " " );  // TODO: fix->use 'space' as the text to render
    else
    {
        expression_ptr name_expr = sym.get_name();
        if (!name_expr) return;
        value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature),*name_expr);
        text = result.to_unicode();
    }
    
    if ( sym.get_text_transform() == UPPERCASE)
    {
        text = text.toUpper();
    }
    else if ( sym.get_text_transform() == LOWERCASE)
    {
        text = text.toLower();
    }
    else if ( sym.get_text_transform() == CAPITALIZE)
    {
        text = text.toTitle(NULL);
    }
    
    agg::trans_affine tr;
    boost::array<double,6> const& m = sym.get_transform();
    tr.load_from(&m[0]);
    
    std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
    boost::optional<mapnik::marker_ptr> marker;
    if ( !filename.empty() )
    {
        marker = marker_cache::instance()->find(filename, true);
    }
    else
    {
        marker.reset(boost::make_shared<mapnik::marker>());
    }
    
    
    if (text.length() > 0 && marker)
    {
        int w = (*marker)->width();
        int h = (*marker)->height();
        
        double px0 = - 0.5 * w;
        double py0 = - 0.5 * h;
        double px1 = 0.5 * w;
        double py1 = 0.5 * h;
        double px2 = px1;
        double py2 = py0;
        double px3 = px0;
        double py3 = py1;
        tr.transform(&px0,&py0);
        tr.transform(&px1,&py1);
        tr.transform(&px2,&py2);
        tr.transform(&px3,&py3);
        box2d<double> label_ext (px0, py0, px1, py1);
        label_ext.expand_to_include(px2, py2);
        label_ext.expand_to_include(px3, py3);
        
        face_set_ptr faces;

        if (sym.get_fontset().size() > 0)
        {
            faces = font_manager_.get_face_set(sym.get_fontset());
        }
        else
        {
            faces = font_manager_.get_face_set(sym.get_face_name());
        }

        stroker_ptr strk = font_manager_.get_stroker();
        if (strk && faces->size() > 0)
        {
            text_renderer<T> ren(pixmap_, faces, *strk);

            ren.set_pixel_size(sym.get_text_size() * scale_factor_);
            ren.set_fill(sym.get_fill());
            ren.set_halo_fill(sym.get_halo_fill());
            ren.set_halo_radius(sym.get_halo_radius() * scale_factor_);
            ren.set_opacity(sym.get_text_opacity());

            placement_finder<label_collision_detector4> finder(detector_);

            string_info info(text);

            faces->get_string_info(info);

            metawriter_with_properties writer = sym.get_metawriter();

            for (unsigned i = 0; i < feature.num_geometries(); ++i)
            {
                geometry_type const& geom = feature.get_geometry(i);
                if (geom.num_points() > 0 )
                {
                    path_type path(t_,geom,prj_trans);

                    label_placement_enum how_placed = sym.get_label_placement();
                    if (how_placed == POINT_PLACEMENT || how_placed == VERTEX_PLACEMENT || how_placed == INTERIOR_PLACEMENT)
                    {
                        // for every vertex, try and place a shield/text
                        geom.rewind(0);
                        placement text_placement(info, sym, scale_factor_, w, h, false);
                        text_placement.avoid_edges = sym.get_avoid_edges();
                        text_placement.allow_overlap = sym.get_allow_overlap();
                        if (writer.first)
                            text_placement.collect_extents =true; // needed for inmem metawriter
                        position const& pos = sym.get_displacement();
                        position const& shield_pos = sym.get_shield_displacement();
                        for( unsigned jj = 0; jj < geom.num_points(); jj++ )
                        {
                            double label_x;
                            double label_y;
                            double z=0.0;

                            if( how_placed == VERTEX_PLACEMENT )
                                geom.vertex(&label_x,&label_y);  // by vertex
                            else if( how_placed == INTERIOR_PLACEMENT )
                                geom.label_interior_position(&label_x,&label_y);
                            else
                                geom.label_position(&label_x, &label_y);  // by middle of line or by point
                            prj_trans.backward(label_x,label_y, z);
                            t_.forward(&label_x,&label_y);

                            label_x += boost::get<0>(shield_pos);
                            label_y += boost::get<1>(shield_pos);

                            finder.find_point_placement( text_placement, placement_options,
                                                         label_x, label_y, 0.0,
                                                         sym.get_line_spacing(),
                                                         sym.get_character_spacing());

                            // check to see if image overlaps anything too, there is only ever 1 placement found for points and verticies
                            if( text_placement.placements.size() > 0)
                            {
                                double x = floor(text_placement.placements[0].starting_x);
                                double y = floor(text_placement.placements[0].starting_y);
                                int px;
                                int py;
                                
                                if( !sym.get_unlock_image() )
                                {
                                    // center image at text center position
                                    // remove displacement from image label
                                    double lx = x - boost::get<0>(pos);
                                    double ly = y - boost::get<1>(pos);
                                    px=int(floor(lx - (0.5 * w))) + 1;
                                    py=int(floor(ly - (0.5 * h))) + 1;
                                    label_ext.re_center(lx,ly);
                                }
                                else
                                {  // center image at reference location
                                    px=int(floor(label_x - 0.5 * w));
                                    py=int(floor(label_y - 0.5 * h));
                                    label_ext.re_center(label_x,label_y);
                                }
                                
                                if ( sym.get_allow_overlap() || detector_.has_placement(label_ext) )
                                {
                                    render_marker(px,py,**marker,tr,sym.get_opacity());

                                    box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[0]);
                                    ren.render(x,y);
                                    detector_.insert(label_ext);
                                    finder.update_detector(text_placement);
                                    if (writer.first) {
                                        writer.first->add_box(label_ext, feature, t_, writer.second);
                                        writer.first->add_text(text_placement, faces, feature, t_, writer.second);
                                    }
                                }
                            }
                        }
                    }

                    else if (geom.num_points() > 1 && how_placed == LINE_PLACEMENT)
                    {
                        placement text_placement(info, sym, scale_factor_, w, h, false);
                        position const& pos = sym.get_displacement();

                        text_placement.avoid_edges = sym.get_avoid_edges();
                        text_placement.additional_boxes.push_back(
                           box2d<double>(-0.5 * label_ext.width() - boost::get<0>(pos),
                                         -0.5 * label_ext.height() - boost::get<1>(pos),
                                         0.5 * label_ext.width() - boost::get<0>(pos),
                                         0.5 * label_ext.height() - boost::get<1>(pos)));
                        finder.find_point_placements<path_type>(text_placement, placement_options, path);

                        for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii)
                        {
                            double x = floor(text_placement.placements[ii].starting_x);
                            double y = floor(text_placement.placements[ii].starting_y);

                            double lx = x - boost::get<0>(pos);
                            double ly = y - boost::get<1>(pos);
                            int px=int(floor(lx - (0.5*w))) + 1;
                            int py=int(floor(ly - (0.5*h))) + 1;
                            label_ext.re_center(lx, ly);

                            render_marker(px,py,**marker,tr,sym.get_opacity());

                            box2d<double> dim = ren.prepare_glyphs(&text_placement.placements[ii]);
                            ren.render(x,y);
                            if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
                        }
                        finder.update_detector(text_placement);
                        if (writer.first) writer.first->add_text(text_placement, faces, feature, t_, writer.second);
                    }
                }
            }
        }
    }
}