static boost::python::tuple getinitargs(const shield_symbolizer& s) { std::string filename = path_processor_type::to_string(*s.get_filename()); //(name, font name, font size, font color, image file, image type, width, height) return boost::python::make_tuple( "TODO",//s.get_name(), s.get_face_name(),s.get_text_size(),s.get_fill(),filename,guess_type(filename)); }
void grid_renderer<T>::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper( sym, feature, prj_trans, width_, height_, scale_factor_, t_, font_manager_, *detector_, query_extent_); bool placement_found = false; text_renderer<T> ren(pixmap_, font_manager_, sym.get_halo_rasterizer(), sym.comp_op(), scale_factor_); text_placement_info_ptr placement; while (helper.next()) { placement_found = true; placements_type const& placements = helper.placements(); for (unsigned int ii = 0; ii < placements.size(); ++ii) { // get_marker_position returns (minx,miny) corner position, // while (currently only) agg_renderer::render_marker newly // expects center position; // until all renderers and shield_symbolizer_helper are // modified accordingly, we must adjust the position here pixel_position pos = helper.get_marker_position(placements[ii]); pos.x += 0.5 * helper.get_marker_width(); pos.y += 0.5 * helper.get_marker_height(); render_marker(feature, pixmap_.get_resolution(), pos, helper.get_marker(), helper.get_image_transform(), sym.get_opacity(), sym.comp_op()); ren.prepare_glyphs(placements[ii]); ren.render_id(feature.id(), placements[ii].center); } } if (placement_found) pixmap_.add_feature(feature); }
void grid_renderer<T>::process(shield_symbolizer const& sym, mapnik::feature_ptr const& feature, proj_transform const& prj_trans) { box2d<double> query_extent; shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper( sym, *feature, prj_trans, width_, height_, scale_factor_, t_, font_manager_, detector_, query_extent); bool placement_found = false; text_renderer<T> ren(pixmap_, font_manager_, *(font_manager_.get_stroker())); text_placement_info_ptr placement; while (helper.next()) { placement_found = true; placements_type &placements = helper.placements(); for (unsigned int ii = 0; ii < placements.size(); ++ii) { render_marker(feature, pixmap_.get_resolution(), helper.get_marker_position(placements[ii]), helper.get_marker(), helper.get_transform(), sym.get_opacity()); ren.prepare_glyphs(&(placements[ii])); ren.render_id(feature->id(), placements[ii].center, 2); } } if (placement_found) pixmap_.add_feature(feature); }
// TODO add lots more... static void setstate (shield_symbolizer& s, boost::python::tuple state) { using namespace boost::python; /*if (len(state) != 1) { PyErr_SetObject(PyExc_ValueError, ("expected 1-item tuple in call to __setstate__; got %s" % state).ptr() ); throw_error_already_set(); }*/ s.set_halo_fill(extract<color>(state[0])); s.set_halo_radius(extract<float>(state[1])); }
void operator () (shield_symbolizer const& sym) { expression_set::const_iterator it; expression_set expressions; sym.get_placement_options()->add_expressions(expressions); for (it=expressions.begin(); it != expressions.end(); it++) { if (*it) boost::apply_visitor(f_attr, **it); } path_expression_ptr const& filename_expr = sym.get_filename(); if (filename_expr) { path_processor_type::collect_attributes(*filename_expr,names_); } collect_transform(sym.get_image_transform()); collect_transform(sym.get_transform()); }
void agg_renderer<T>::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper( sym, feature, prj_trans, width_, height_, scale_factor_, t_, font_manager_, *detector_, query_extent_); text_renderer<T> ren(*current_buffer_, font_manager_, *(font_manager_.get_stroker())); while (helper.next()) { placements_type &placements = helper.placements(); for (unsigned int ii = 0; ii < placements.size(); ++ii) { // get_marker_position returns (minx,miny) corner position, // while (currently only) agg_renderer::render_marker newly // expects center position; // until all renderers and shield_symbolizer_helper are // modified accordingly, we must adjust the position here pixel_position pos = helper.get_marker_position(placements[ii]); pos.x += 0.5 * helper.get_marker_width(); pos.y += 0.5 * helper.get_marker_height(); render_marker(pos, helper.get_marker(), helper.get_image_transform(), sym.get_opacity(), sym.comp_op()); ren.prepare_glyphs(&(placements[ii])); ren.render(placements[ii].center); } } }
void agg_renderer<T>::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { for (std::list<feature_ptr>::iterator f = featureList_->begin(); f != featureList_->end(); f++) { feature_ptr featurePtr = *f; shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper( sym, *featurePtr, prj_trans, width_, height_, scale_factor_, t_, font_manager_, *detector_, query_extent_); text_renderer<T> ren(*current_buffer_, font_manager_, *(font_manager_.get_stroker()), sym.comp_op(), scale_factor_); while (helper.next()) { placements_type const& placements = helper.placements(); for (unsigned int ii = 0; ii < placements.size(); ++ii) { // get_marker_position returns (minx,miny) corner position, // while (currently only) agg_renderer::render_marker newly // expects center position; // until all renderers and shield_symbolizer_helper are // modified accordingly, we must adjust the position here pixel_position pos = helper.get_marker_position(placements[ii]); // pos.x += 0.5 * helper.get_marker_width(); // pos.y += 0.5 * helper.get_marker_height(); // render_marker(pos, // helper.get_marker(), // helper.get_image_transform(), // sym.get_opacity(), // sym.comp_op()); marker const& marker_ = helper.get_marker(); image_data_32 const& src = **marker_.get_bitmap_data(); double width = src.width(); double height = src.height(); const double shifted = 0; double markerX = pos.x + shifted, markerY = height_ - pos.y - shifted - height; glMatrixLoadIdentityEXT(GL_PROJECTION); glMatrixOrthoEXT(GL_PROJECTION, 0, width_, height_, 0, -1, 1); glMatrixLoadIdentityEXT(GL_MODELVIEW); GLubyte cmd[5]; GLfloat coord[8]; int m = 0, n = 0; cmd[m++] = GL_MOVE_TO_NV; coord[n++] = markerX; coord[n++] = markerY; cmd[m++] = GL_LINE_TO_NV; coord[n++] = markerX + width; coord[n++] = markerY; cmd[m++] = GL_LINE_TO_NV; coord[n++] = markerX + width; coord[n++] = markerY + height; cmd[m++] = GL_LINE_TO_NV; coord[n++] = markerX; coord[n++] = markerY + height; cmd[m++] = GL_CLOSE_PATH_NV; glPathCommandsNV(pathObject_, m, cmd, n, GL_FLOAT, coord); // glStencilFunc(GL_NOTEQUAL, 0, 0x1F); // glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); //makeFaceTexture(TEXTURE_FACE); static GLuint texName; glGenTextures(1, &texName); glBindTexture(GL_TEXTURE_2D, texName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)src.getBytes()); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); GLfloat data[2][3] = { { 1,0,0 }, /* s = 1*x + 0*y + 0 */ { 0,1,0 } }; /* t = 0*x + 1*y + 0 */ //glEnable(GL_STENCIL_TEST); //glColor3f(1,1,1); glEnable(GL_TEXTURE_2D); glPathTexGenNV(GL_TEXTURE0, GL_PATH_OBJECT_BOUNDING_BOX_NV, 2, &data[0][0]); glStencilFillPathNV(pathObject_, GL_COUNT_UP_NV, 0x1F); glCoverFillPathNV(pathObject_, GL_BOUNDING_BOX_NV); glDisable(GL_TEXTURE_2D); pathObject_++; //Text rendering //ren.prepare_glyphs(placements[ii]); //ren.render(placements[ii].center); const int size = placements[ii].num_nodes(); int strokeEnable = 0; char word[size]; unsigned red,green,blue,alpha; double textWidth = 0; double textHeight = 0; color textColor,strokeColor; double opacity = 0.0; for (int i = 0; i < placements[ii].num_nodes(); i++) { char_info_ptr c; double x, y, angle; placements[ii].vertex(&c, &x, &y, &angle); word[i] = (char)c->c; textWidth += c->width; textHeight = c->height(); double halo_radius = c->format->halo_radius; if (halo_radius > 0.0 && halo_radius < 1024.0){ strokeEnable = 1; // red = c->format->halo_fill.red(); // green = c->format->halo_fill.green(); // blue = c->format->halo_fill.blue(); // alpha = c->format->halo_fill.alpha(); strokeColor = c->format->halo_fill; } textColor = c->format->fill; opacity = c->format->text_opacity; } double posX = placements[ii].center.x, posY = placements[ii].center.y; int centerText = textWidth / 2; double posTextY = height_ - markerY - (height)/2; double posTextX = posX - centerText; if(posTextY <= height_ / 2) posTextY -= 5; if(posTextX >= width_ / 2) posTextX += 5; if(!strokeEnable){ render_text(size, word, posTextX, posTextY,textColor, opacity); } if(strokeEnable){ render_text(size, word, posTextX, posTextY,textColor,strokeColor,opacity); } } } } }
static boost::python::tuple getstate(const shield_symbolizer& s) { return boost::python::make_tuple(s.get_halo_fill(),s.get_halo_radius()); }
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); } } } } } }