diff --git a/src/agg_renderer.cpp b/src/agg_renderer.cpp index c011f97dd..80e7e22fb 100644 --- a/src/agg_renderer.cpp +++ b/src/agg_renderer.cpp @@ -476,40 +476,81 @@ namespace mapnik ren.set_pixel_size(sym.get_text_size()); ren.set_fill(sym.get_fill()); + ren.set_halo_fill(sym.get_halo_fill()); + ren.set_halo_radius(sym.get_halo_radius()); + + placement_finder finder(detector_); string_info info(text); - - faces->get_string_info(info); - placement_finder finder(detector_); + faces->get_string_info(info); + + + int w = data->width(); + int h = data->height(); unsigned num_geom = feature.num_geometries(); for (unsigned i=0;i 0) // don't bother with empty geometries + geometry2d const& geom = feature.get_geometry(i); + if (geom.num_points() > 0 ) { path_type path(t_,geom,prj_trans); placement text_placement(info, sym); text_placement.avoid_edges = sym.get_avoid_edges(); - finder.find_point_placements(text_placement,path); - - for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) - { - int w = data->width(); - int h = data->height(); - - double x = text_placement.placements[ii].starting_x; - double y = text_placement.placements[ii].starting_y; - - int px=int(x - (w/2)); - int py=int(y - (h/2)); - - pixmap_.set_rectangle_alpha(px,py,*data); - - Envelope dim = ren.prepare_glyphs(&text_placement.placements[ii]); + if (sym.get_label_placement() == POINT_PLACEMENT) + { + double label_x; + double label_y; + double z=0.0; + geom.label_position(&label_x, &label_y); + prj_trans.backward(label_x,label_y, z); + t_.forward(&label_x,&label_y); + finder.find_point_placement(text_placement,label_x,label_y); + + 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; + // remove displacement from image label + position pos = sym.get_displacement(); + double lx = x - boost::get<0>(pos); + double ly = y - boost::get<1>(pos); + int px=int(lx - (0.5 * w)) ; + int py=int(ly - (0.5 * h)) ; + Envelope label_ext (floor(lx - 0.5 * w), floor(ly - 0.5 * h), ceil (lx + 0.5 * w), ceil (ly + 0.5 * h)); - ren.render(x,y); + if ( detector_.has_placement(label_ext)) + { + pixmap_.set_rectangle_alpha(px,py,*data); + Envelope dim = ren.prepare_glyphs(&text_placement.placements[ii]); + ren.render(x,y); + detector_.insert(label_ext); + } + } + finder.update_detector(text_placement); + } + + else if (geom.num_points() > 1 && sym.get_label_placement() == LINE_PLACEMENT) + { + finder.find_point_placements(text_placement,path); + + for (unsigned int ii = 0; ii < text_placement.placements.size(); ++ ii) + { + int w = data->width(); + int h = data->height(); + double x = text_placement.placements[ii].starting_x; + double y = text_placement.placements[ii].starting_y; + + int px=int(x - (w/2)); + int py=int(y - (h/2)); + + pixmap_.set_rectangle_alpha(px,py,*data); + + Envelope dim = ren.prepare_glyphs(&text_placement.placements[ii]); + ren.render(x,y); + } + finder.update_detector(text_placement); } } } @@ -722,6 +763,7 @@ namespace mapnik prj_trans.backward(label_x,label_y, z); t_.forward(&label_x,&label_y); finder.find_point_placement(text_placement,label_x,label_y); + finder.update_detector(text_placement); } else //LINE_PLACEMENT { diff --git a/src/load_map.cpp b/src/load_map.cpp index e873eb452..30c539618 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -849,7 +849,29 @@ namespace mapnik { throw config_error(std::string("Must have face_name or fontset_name")); } + // text displacement + int dx = get_attr(sym, "dx", 0); + int dy = get_attr(sym, "dy", 0); + shield_symbol.set_displacement(dx,dy); + + label_placement_e placement = + get_attr(sym, "placement", POINT_PLACEMENT); + shield_symbol.set_label_placement( placement ); + + // halo fill and radius + optional halo_fill = get_opt_attr(sym, "halo_fill"); + if (halo_fill) + { + shield_symbol.set_halo_fill( * halo_fill ); + } + optional halo_radius = + get_opt_attr(sym, "halo_radius"); + if (halo_radius) + { + shield_symbol.set_halo_radius(*halo_radius); + } + // minimum distance between labels optional min_distance = get_opt_attr(sym, "min_distance"); diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp index dcf338c50..b960b803a 100644 --- a/src/placement_finder.cpp +++ b/src/placement_finder.cpp @@ -62,7 +62,7 @@ namespace mapnik max_char_angle_delta(sym.get_max_char_angle_delta()), minimum_distance(sym.get_minimum_distance()), avoid_edges(sym.get_avoid_edges()), - has_dimensions(true), + has_dimensions(false), dimensions(std::make_pair(sym.get_image()->width(), sym.get_image()->height())) { @@ -309,7 +309,7 @@ namespace mapnik for (unsigned i = 0; i < p.info.num_characters(); i++) { - character_info ci;; + character_info ci; ci = p.info.at(i); unsigned c = ci.character; @@ -325,7 +325,7 @@ namespace mapnik else { current_placement->add_node(c, x, y, 0.0); - + Envelope e; if (p.has_dimensions) { @@ -355,7 +355,7 @@ namespace mapnik x += ci.width; } p.placements.push_back(current_placement.release()); - update_detector(p); + //update_detector(p); }