Ejemplo n.º 1
0
static void scale_render(GpsdViewerOsd *self, OsmGpsMap *map)
{
    GpsdViewerOsdScale *scale = self->priv->scale;

    if(!scale->surface)
        return;

    /* this only needs to be rendered if the zoom or latitude has changed */
    gint zoom;
    gfloat lat;
    g_object_get(G_OBJECT(map), "zoom", &zoom, "latitude", &lat, NULL);
    if(zoom == scale->zoom && lat == scale->lat)
        return;

    scale->zoom = zoom;
    scale->lat = lat;

    float m_per_pix = osm_gps_map_get_scale(map);

    /* first fill with transparency */
    g_assert(scale->surface);
    cairo_t *cr = cairo_create(scale->surface);
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0);
    // pink for testing:    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.2);
    cairo_paint(cr);
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);

    /* determine the size of the scale width in meters */
    float width = (GPSD_VIEWER_OSD_SCALE_W-GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6) * m_per_pix;

    /* scale this to useful values */
    int exp = logf(width)*M_LOG10E;
    int mant = width/pow(10,exp);
    int width_metric = mant * pow(10,exp);
    char *dist_str = NULL;
    if(width_metric<1000)
        dist_str = g_strdup_printf("%u m", width_metric);
    else
        dist_str = g_strdup_printf("%u km", width_metric/1000);
    width_metric /= m_per_pix;

    /* and now the hard part: scale for useful imperial values :-( */
    /* try to convert to feet, 1ft == 0.3048 m */
    width /= 0.3048;
    float imp_scale = 0.3048;
    char *dist_imp_unit = "ft";

    if(width >= 100) {
        /* 1yd == 3 feet */
        width /= 3.0;
        imp_scale *= 3.0;
        dist_imp_unit = "yd";

        if(width >= 1760.0) {
            /* 1mi == 1760 yd */
            width /= 1760.0;
            imp_scale *= 1760.0;
            dist_imp_unit = "mi";
        }
    }

    /* also convert this to full tens/hundreds */
    exp = logf(width)*M_LOG10E;
    mant = width/pow(10,exp);
    int width_imp = mant * pow(10,exp);
    char *dist_str_imp = g_strdup_printf("%u %s", width_imp, dist_imp_unit);

    /* convert back to pixels */
    width_imp *= imp_scale;
    width_imp /= m_per_pix;

    cairo_select_font_face (cr, "Sans",
                            CAIRO_FONT_SLANT_NORMAL,
                            CAIRO_FONT_WEIGHT_BOLD);
    cairo_set_font_size (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE);
    cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);

    cairo_text_extents_t extents;
    cairo_text_extents (cr, dist_str, &extents);

    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
    cairo_set_line_width (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6);
    cairo_move_to (cr, 2*GPSD_VIEWER_OSD_SCALE_FD, GPSD_VIEWER_OSD_SCALE_H2-GPSD_VIEWER_OSD_SCALE_FD);
    cairo_text_path (cr, dist_str);
    cairo_stroke (cr);
    cairo_move_to (cr, 2*GPSD_VIEWER_OSD_SCALE_FD,
                   GPSD_VIEWER_OSD_SCALE_H2+GPSD_VIEWER_OSD_SCALE_FD + extents.height);
    cairo_text_path (cr, dist_str_imp);
    cairo_stroke (cr);

    cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
    cairo_move_to (cr, 2*GPSD_VIEWER_OSD_SCALE_FD, GPSD_VIEWER_OSD_SCALE_H2-GPSD_VIEWER_OSD_SCALE_FD);
    cairo_show_text (cr, dist_str);
    cairo_move_to (cr, 2*GPSD_VIEWER_OSD_SCALE_FD,
                   GPSD_VIEWER_OSD_SCALE_H2+GPSD_VIEWER_OSD_SCALE_FD + extents.height);
    cairo_show_text (cr, dist_str_imp);

    g_free(dist_str);
    g_free(dist_str_imp);

    /* draw white line */
    cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);
    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
    cairo_set_line_width (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/3);
    cairo_move_to (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6, GPSD_VIEWER_OSD_SCALE_M);
    cairo_rel_line_to (cr, 0,  GPSD_VIEWER_OSD_SCALE_TICK);
    cairo_rel_line_to (cr, width_metric, 0);
    cairo_rel_line_to (cr, 0, -GPSD_VIEWER_OSD_SCALE_TICK);
    cairo_stroke(cr);
    cairo_move_to (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6, GPSD_VIEWER_OSD_SCALE_I);
    cairo_rel_line_to (cr, 0, -GPSD_VIEWER_OSD_SCALE_TICK);
    cairo_rel_line_to (cr, width_imp, 0);
    cairo_rel_line_to (cr, 0, +GPSD_VIEWER_OSD_SCALE_TICK);
    cairo_stroke(cr);

    /* draw black line */
    cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
    cairo_set_line_width (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6);
    cairo_move_to (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6, GPSD_VIEWER_OSD_SCALE_M);
    cairo_rel_line_to (cr, 0,  GPSD_VIEWER_OSD_SCALE_TICK);
    cairo_rel_line_to (cr, width_metric, 0);
    cairo_rel_line_to (cr, 0, -GPSD_VIEWER_OSD_SCALE_TICK);
    cairo_stroke(cr);
    cairo_move_to (cr, GPSD_VIEWER_OSD_SCALE_FONT_SIZE/6, GPSD_VIEWER_OSD_SCALE_I);
    cairo_rel_line_to (cr, 0, -GPSD_VIEWER_OSD_SCALE_TICK);
    cairo_rel_line_to (cr, width_imp, 0);
    cairo_rel_line_to (cr, 0, +GPSD_VIEWER_OSD_SCALE_TICK);
    cairo_stroke(cr);

    cairo_destroy(cr);
}
Ejemplo n.º 2
0
static int dist2pixel(OsmGpsMap *map, float km) {
  return 1000.0*km/osm_gps_map_get_scale(map);
}