Ejemplo n.º 1
0
// Before placing a new label we need to see if the label overlaps over
// previously placed labels. This algorithm will be refactored a bit to try
// NE SE SW NW placements in the future.
void
try_and_insert_placement(simplet_lithograph_t *litho, PangoLayout *layout, double x, double y){
  int width, height;
  // Find the computed width and height of a layout in image pixels
  pango_layout_get_pixel_size(layout, &width, &height);
  simplet_bounds_t *bounds = simplet_bounds_new();
  if(!bounds) return;
  // Create a bounds to test for intersection
  simplet_bounds_extend(bounds, floor(x - width / 2), floor(y - height / 2));
  simplet_bounds_extend(bounds, floor(x + width / 2), floor(y + height / 2));

  // Iterate through the list of already placed labels and check for overlaps.
  simplet_listiter_t *iter = simplet_get_list_iter(litho->placements);
  placement_t *placement;
  while((placement = (placement_t *) simplet_list_next(iter))){
    if(simplet_bounds_intersects(placement->bounds, bounds)){
      simplet_bounds_free(bounds);
      g_object_unref(layout);
      simplet_list_iter_free(iter);
      return;
    }
  }

  // If we get here we can create and insert a new placement.
  placement_t *plc = placement_new(layout, bounds);
  if(!plc) {
    simplet_bounds_free(bounds);
    g_object_unref(layout);
    return;
  }

  simplet_list_push(litho->placements, (void *)plc);
}
Ejemplo n.º 2
0
// Process a layer and add labels.
simplet_status_t
simplet_layer_process(simplet_layer_t *layer, simplet_map_t *map, simplet_lithograph_t *litho, cairo_t *ctx){
  simplet_listiter_t *iter; OGRDataSourceH source;
  if(!(source = OGROpenShared(layer->source, 0, NULL)))
    return set_error(layer, SIMPLET_OGR_ERR, "error opening layer source");

  // Retain the datasource because we want to cache open connections to a
  // data source like postgres.
  if(OGR_DS_GetRefCount(source) == 1) OGR_DS_Reference(source);
  if(!(iter = simplet_get_list_iter(layer->filters))){
    OGRReleaseDataSource(source);
    return set_error(layer, SIMPLET_OOM, "out of memory getting list iterator");
  }

  // Loop through the layer's filters and process them.
  simplet_filter_t *filter;
  simplet_status_t status = SIMPLET_OK;
  while((filter = simplet_list_next(iter))) {
    status = simplet_filter_process(filter, map, source, litho, ctx);

    if(status != SIMPLET_OK){
      simplet_list_iter_free(iter);
      OGRReleaseDataSource(source);
      return status;
    }

    simplet_lithograph_apply(litho, filter->styles);
  }
  OGRReleaseDataSource(source);
  return SIMPLET_OK;
}
Ejemplo n.º 3
0
// Apply the labels to the map.
void
simplet_lithograph_apply(simplet_lithograph_t *litho, simplet_list_t *styles){
  simplet_listiter_t *iter = simplet_get_list_iter(litho->placements);
  placement_t *placement;
  cairo_save(litho->ctx);
  while((placement = (placement_t *) simplet_list_next(iter))){
    if(placement->placed == TRUE) continue;
    cairo_move_to(litho->ctx, placement->bounds->nw.x, placement->bounds->se.y);

    // Draw the placement
    pango_cairo_layout_path(litho->ctx, placement->layout);

    placement->placed = TRUE;
  }
  simplet_apply_styles(litho->ctx, styles, "text-stroke-weight", "text-stroke-color", "color",  NULL);

  // Apply and draw various outline options.
  cairo_restore(litho->ctx);
}