Example #1
0
/*
 * Since this function is used for every drawn trackpoint - it can get called alot
 * Thus x & y position factors are calculated once on zoom changes,
 *  avoiding the need to do it here all the time.
 * For good measure the half width and height values are also pre calculated too.
 */
void vik_viewport_coord_to_screen ( VikViewport *vvp, const VikCoord *coord, int *x, int *y )
{
  static VikCoord tmp;
  g_return_if_fail ( vvp != NULL );

  if ( coord->mode != vvp->coord_mode )
  {
    g_warning ( "Have to convert in vik_viewport_coord_to_screen! This should never happen!");
    vik_coord_copy_convert ( coord, vvp->coord_mode, &tmp );
    coord = &tmp;
  }

  if ( vvp->coord_mode == VIK_COORD_UTM ) {
    struct UTM *center = (struct UTM *) &(vvp->center);
    struct UTM *utm = (struct UTM *) coord;
    if ( center->zone != utm->zone && vvp->one_utm_zone )
    {
      *x = *y = VIK_VIEWPORT_UTM_WRONG_ZONE;
      return;
    }

    *x = ( (utm->easting - center->easting) / vvp->xmpp ) + (vvp->width_2) -
  	  (center->zone - utm->zone ) * vvp->utm_zone_width / vvp->xmpp;
    *y = (vvp->height_2) - ( (utm->northing - center->northing) / vvp->ympp );
  } else if ( vvp->coord_mode == VIK_COORD_LATLON ) {
    struct LatLon *center = (struct LatLon *) &(vvp->center);
    struct LatLon *ll = (struct LatLon *) coord;
    double xx,yy;
    if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_LATLON ) {
      *x = vvp->width_2 + ( MERCATOR_FACTOR(vvp->xmpp) * (ll->lon - center->lon) );
      *y = vvp->height_2 + ( MERCATOR_FACTOR(vvp->ympp) * (center->lat - ll->lat) );
    } else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_EXPEDIA ) {
      calcxy ( &xx, &yy, center->lon, center->lat, ll->lon, ll->lat, vvp->xmpp * ALTI_TO_MPP, vvp->ympp * ALTI_TO_MPP, vvp->width_2, vvp->height_2 );
      *x = xx; *y = yy;
    } else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_MERCATOR ) {
      *x = vvp->width_2 + ( MERCATOR_FACTOR(vvp->xmpp) * (ll->lon - center->lon) );
      *y = vvp->height_2 + ( MERCATOR_FACTOR(vvp->ympp) * ( MERCLAT(center->lat) - MERCLAT(ll->lat) ) );
    }
  }
}
Example #2
0
/*
 * Draw a grid over the map
 */
void
draw_grid (GtkWidget * widget)
{
	int count;
	gdouble step, step_pow10;
	gdouble lat, lon;
	gdouble lat_ul, lon_ul;
	gdouble lat_ll, lon_ll;
	gdouble lat_ur, lon_ur;
	gdouble lat_lr, lon_lr;

	gdouble lat_min, lon_min;
	gdouble lat_max, lon_max;

	gchar precision[10];
	gint iteration_count =0;
	
	if ( mydebug >50 ) 
	    fprintf(stderr , "draw_grid()\n");


	// calculate the start and stop for lat/lon according to the displayed section
	calcxytopos (0, 0, &lat_ul, &lon_ul, current.zoom);
	calcxytopos (0, gui_status.mapview_y, &lat_ll, &lon_ll, current.zoom);
	calcxytopos (gui_status.mapview_x, 0, &lat_ur, &lon_ur, current.zoom);
	calcxytopos (gui_status.mapview_x, gui_status.mapview_y, &lat_lr, &lon_lr, current.zoom);

	// add more lines as the scale increases

	// Calculate distance between grid lines
	step = (gdouble) current.mapscale / 2000000.0 / current.zoom;

	/* round step to one sig. digit */
	step_pow10= floor( log10(step) );  // add -1 for 2 sig digits, -2 for 3, etc.

/* FIXME: use round(x) instead of floor(x+0.5) ??? */
//	step = pow(10, step_pow10) * round(step * pow(10, -1 * step_pow10));
	step = pow(10, step_pow10) * floor(0.5+ (step * pow(10, -1 * step_pow10)));

/* TODO: respect user's prefered DMS style; round and display accordingly:
	DDD.DDDDD, DDD MM.MMMM, DDD MM SS.SSSS

   TODO: round on "nice numbers":
	deg, min, sec: 30, 15, 10, 5, 2, 1
	decimal deg: .5, .25, .1, .05, 0.02, 0.1

     see SourceForge wish #2375742 for some sample GPL'd code to do that
       (from GRASS GIS's ps/ps.map/ps_fclrtbl.c#L162)
  */

	if (step != step || step == 0) {
	    fprintf(stderr, "?? draw_grid(): distance step is %f, "
			    "mapscale is 1:%ld\n", step, current.mapscale);
	    return;
	}

	do {
	    if (step >= 1)		g_snprintf (precision, sizeof (precision), "%%.0f");
	    else if (step >= .1)	g_snprintf (precision, sizeof (precision), "%%.1f");
	    else if (step >= .01)	g_snprintf (precision, sizeof (precision), "%%.2f");
	    else if (step >= .001)	g_snprintf (precision, sizeof (precision), "%%.3f");
	    else if (step >= .0001)	g_snprintf (precision, sizeof (precision), "%%.4f");
	    else           		g_snprintf (precision, sizeof (precision), "%%.5f");

	    if (current.mapscale / current.zoom < 50000000)
		{
		    lat_min = min (lat_ll, lat_ul) - step;
		    lat_max = max (lat_lr, lat_ur) + step;
		    lon_min = min (lon_ll, lon_ul) - step;
		    lon_max = max (lon_lr, lon_ur) + step;
		}
	    else
		{
		    lat_min = -90;
		    lat_max = 90;
		    lon_min = -180;
		    lon_max = 180;
		}
	    lat_min = floor (lat_min / step) * step;
	    lon_min = floor (lon_min / step) * step;

	    if ( mydebug > 20 )
		printf ("Draw Grid: (%.2f,%.2f) - (%.2f,%.2f) Step %f for Ef.Scale %ld Zoom %d\n",
			lat_min, lon_min, lat_max, lon_max, step,
			current.mapscale/current.zoom, current.zoom);
	    if ( mydebug > 40 )
		{
		    printf ("Draw Grid: (%.2f) Iterations for lat\n", (lat_max-lat_min)/step);
		    printf ("Draw Grid: (%.2f) Iterations for lon\n", (lon_max-lon_min)/step);
		}

	    // limit number of grid iterations to between 20 and 45 iterations
	    iteration_count = ((lat_max-lat_min)/step) * ((lon_max-lon_min)/step);
	    if ( iteration_count > 45 )
		step = step * 2;
	    else if ( iteration_count < 20 )
		step = step / 3.;

	} while ( iteration_count > 45 || iteration_count < 20 );


	// Loop over desired lat/lon  
	count = 0;
	for (lon = lon_min; lon <= lon_max; lon = lon + step)
	    {
		for (lat = lat_min; lat <= lat_max; lat = lat + step)
		    {
			gint posxdest11, posydest11;
			gint posxdest12, posydest12;
			gint posxdest21, posydest21;
			gint posxdest22, posydest22;
			gint posxdist, posydist;
			gchar str[200];

			count++;
			calcxy (&posxdest11, &posydest11, lon,        max(-90,lat)       , current.zoom);
			calcxy (&posxdest12, &posydest12, lon,        min( 90,lat + step), current.zoom);
			calcxy (&posxdest21, &posydest21, lon + step, max(-90,lat),        current.zoom);
			calcxy (&posxdest22, &posydest22, lon + step, min( 90,lat + step), current.zoom);

			if (((posxdest11 >= 0) && (posxdest11 < gui_status.mapview_x) &&
			     (posydest11 >= 0) && (posydest11 < gui_status.mapview_y))
			    ||
			    ((posxdest22 >= 0) && (posxdest22 < gui_status.mapview_x) &&
			     (posydest22 >= 0) && (posydest22 < gui_status.mapview_y))
			    ||
			    ((posxdest21 >= 0) && (posxdest21 < gui_status.mapview_x) &&
			     (posydest21 >= 0) && (posydest21 < gui_status.mapview_y))
			    ||
			    ((posxdest12 >= 0) && (posxdest12 < gui_status.mapview_x) &&
			     (posydest12 >= 0) && (posydest12 < gui_status.mapview_y)))
			    {
				// TODO: add linethickness 2 for Mayor Lines
				// Set Drawing Mode
				gdk_gc_set_function (kontext_map, GDK_XOR);
				gdk_gc_set_foreground (kontext_map, &colors.darkgrey);
				gdk_gc_set_line_attributes (kontext_map, 1, GDK_LINE_SOLID, 0, 0);

				gdk_draw_line (drawable, kontext_map, posxdest11,
					       posydest11, posxdest21,
					       posydest21);
				gdk_draw_line (drawable, kontext_map, posxdest11,
					       posydest11, posxdest12,
					       posydest12);
			    
				// Text lon
				g_snprintf (str, sizeof (str), precision, lon);

				posxdist = (posxdest12 - posxdest11) / 4;
				posydist = (posydest12 - posydest11) / 4;
				draw_grid_text (widget, 
						posxdest11 + posxdist,
						posydest11 + posydist, str);
				
				// Text lat
				g_snprintf (str, sizeof (str), precision, lat);
					    
				posxdist = (posxdest21 - posxdest11) / 4;
				posydist = (posydest21 - posydest11) / 4;
				draw_grid_text (widget, 
						posxdest11 + posxdist,
						posydest11 + posydist-5, str);
			    }
		    }
	    }
	if ( mydebug > 30 )
	    printf ("draw_grid loops: %d\n", count);
}
Example #3
0
/* ****************************************************************************
 * draw lines showing the route
 */
void
draw_route (void)
{
	GdkSegment *route_seg;

	gint destpos_x, destpos_y, curpos_x, curpos_y;
	gint i, j;
	gint t = 0;
	gchar t_routept[5];
	GtkTreeIter iter_route;
	gdouble t_lon, t_lat;
	
	if (route.items < 1)
		return;

	i = (route.items + 5);
	route_seg = g_new0 (GdkSegment, i);

	if (local_config.use_database)
	{
	/* poi mode */	
		g_snprintf (t_routept, sizeof (t_routept), "%d",
			(route.pointer));
		gtk_tree_model_get_iter_from_string
			(GTK_TREE_MODEL (route_list_tree),
			&iter_route, t_routept);

		calcxy (&curpos_x, &curpos_y,
			coords.current_lon, coords.current_lat, current.zoom);
		(route_seg)->x1 = curpos_x;
		(route_seg)->y1 = curpos_y;

		do
		{
			gtk_tree_model_get
				(GTK_TREE_MODEL (route_list_tree), &iter_route,
				ROUTE_LON, &t_lon, ROUTE_LAT, &t_lat, -1);
			if (t != 0)
			{
				(route_seg + t)->x1 = (route_seg + t - 1)->x2;
				(route_seg + t)->y1 = (route_seg + t - 1)->y2;
			}
			calcxy (&destpos_x, &destpos_y, t_lon, t_lat,
				current.zoom);
			(route_seg + t)->x2 = destpos_x;
			(route_seg + t)->y2 = destpos_y;
			t++;
		}
		while (gtk_tree_model_iter_next (GTK_TREE_MODEL
			(route_list_tree), &iter_route));
	}
	else
	{
	/* waypoints mode */
		/* start beginning with actual route.pointer */
		for (j = route.pointer; j < route.items; j++)
		{
			/* start drawing with current_pos */
			if (j == route.pointer)
			{
				calcxy (&curpos_x, &curpos_y,
					coords.current_lon,
					coords.current_lat, current.zoom);
				(route_seg + t)->x1 = curpos_x;
				(route_seg + t)->y1 = curpos_y;
			}
			else
			{
				(route_seg + t)->x1 = (route_seg + t - 1)->x2;
				(route_seg + t)->y1 = (route_seg + t - 1)->y2;
			}
			calcxy (&destpos_x, &destpos_y, (routelist +
				j)->lon, (routelist + j)->lat, current.zoom);
			(route_seg + t)->x2 = destpos_x;
			(route_seg + t)->y2 = destpos_y;
			t++;
		}
	}

	gdk_gc_set_foreground (kontext_map, &colors.route);
	gdk_gc_set_background (kontext_map, &colors.white);
	gdk_gc_set_line_attributes (kontext_map, 4, GDK_LINE_ON_OFF_DASH, 0, 0);

	gdk_gc_set_dashes (kontext_map, 0, (gpointer) linestyles[local_config.style_route], 4);
	gdk_gc_set_function (kontext_map, GDK_COPY);
	gdk_draw_segments (drawable, kontext_map, (GdkSegment *) route_seg, t);
	g_free (route_seg);
}