/** * champlain_map_source_get_renderer: * @map_source: a #ChamplainMapSource * * Get the renderer used for tiles rendering. * * Returns: (transfer none): the renderer. * * Since: 0.8 */ ChamplainRenderer * champlain_map_source_get_renderer (ChamplainMapSource *map_source) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), NULL); return map_source->priv->renderer; }
/** * champlain_map_source_get_tile_size: * @map_source: a #ChamplainMapSource * * Gets map source's tile size. * * Returns: the tile's size (width and height) in pixels for this map source * * Since: 0.4 */ guint champlain_map_source_get_tile_size (ChamplainMapSource *map_source) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), 0); return CHAMPLAIN_MAP_SOURCE_GET_CLASS (map_source)->get_tile_size (map_source); }
/** * champlain_map_source_get_next_source: * @map_source: a #ChamplainMapSource * * Get the next source in the chain. * * Returns: (transfer none): the next source in the chain. * * Since: 0.6 */ ChamplainMapSource * champlain_map_source_get_next_source (ChamplainMapSource *map_source) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), NULL); return map_source->priv->next_source; }
/** * champlain_map_source_get_projection: * @map_source: a #ChamplainMapSource * * Gets map source's projection. * * Returns: the map source's projection. * * Since: 0.4 */ ChamplainMapProjection champlain_map_source_get_projection (ChamplainMapSource *map_source) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), CHAMPLAIN_MAP_PROJECTION_MERCATOR); return CHAMPLAIN_MAP_SOURCE_GET_CLASS (map_source)->get_projection (map_source); }
/** * champlain_map_source_get_license_uri: * @map_source: a #ChamplainMapSource * * Gets map source's license URI. * * Returns: the map source's license URI. * * Since: 0.4 */ const gchar * champlain_map_source_get_license_uri (ChamplainMapSource *map_source) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), NULL); return CHAMPLAIN_MAP_SOURCE_GET_CLASS (map_source)->get_license_uri (map_source); }
/** * champlain_map_source_fill_tile: * @map_source: a #ChamplainMapSource * @tile: a #ChamplainTile * * Fills the tile with image data (either from cache, network or rendered * locally). * * Since: 0.4 */ void champlain_map_source_fill_tile (ChamplainMapSource *map_source, ChamplainTile *tile) { g_return_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source)); CHAMPLAIN_MAP_SOURCE_GET_CLASS (map_source)->fill_tile (map_source, tile); }
/** * champlain_map_source_get_column_count: * @map_source: a #ChamplainMapSource * @zoom_level: the zoom level * * Gets the number of tiles in a column at this zoom level for this map * source. * * Returns: the number of tiles in a column * * Since: 0.4 */ guint champlain_map_source_get_column_count (ChamplainMapSource *map_source, guint zoom_level) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), 0); /* FIXME: support other projections */ return (zoom_level != 0) ? 2 << (zoom_level - 1) : 1; }
static const gchar * get_license_uri (ChamplainMapSource *map_source) { g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), NULL); ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source); g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), NULL); return champlain_map_source_get_license_uri (next_source); }
static ChamplainMapProjection get_projection (ChamplainMapSource *map_source) { g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), CHAMPLAIN_MAP_PROJECTION_MERCATOR); ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source); g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), CHAMPLAIN_MAP_PROJECTION_MERCATOR); return champlain_map_source_get_projection (next_source); }
static guint get_tile_size (ChamplainMapSource *map_source) { g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), 0); ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source); g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), 0); return champlain_map_source_get_tile_size (next_source); }
static void fill_tile (ChamplainMapSource *map_source, ChamplainTile *tile) { g_return_if_fail (CHAMPLAIN_IS_MEMORY_CACHE (map_source)); g_return_if_fail (CHAMPLAIN_IS_TILE (tile)); ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source); if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE) return; if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED) { ChamplainMemoryCache *memory_cache = CHAMPLAIN_MEMORY_CACHE (map_source); ChamplainMemoryCachePrivate *priv = memory_cache->priv; ChamplainRenderer *renderer; GList *link; gchar *key; key = generate_queue_key (memory_cache, tile); link = g_hash_table_lookup (priv->hash_table, key); g_free (key); if (link) { QueueMember *member = link->data; move_queue_member_to_head (priv->queue, link); renderer = champlain_map_source_get_renderer (map_source); g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer)); g_object_ref (map_source); g_object_ref (tile); g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source); champlain_renderer_set_data (renderer, member->data, member->size); champlain_renderer_render (renderer, tile); return; } } if (CHAMPLAIN_IS_MAP_SOURCE (next_source)) champlain_map_source_fill_tile (next_source, tile); else if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADED) { /* if we have some content, use the tile even if it wasn't validated */ champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE); champlain_tile_display_content (tile); } }
/** * champlain_map_source_get_x: * @map_source: a #ChamplainMapSource * @zoom_level: the zoom level * @longitude: a longitude * * Gets the x position on the map using this map source's projection. * (0, 0) is located at the top left. * * Returns: the x position * * Since: 0.4 */ gdouble champlain_map_source_get_x (ChamplainMapSource *map_source, guint zoom_level, gdouble longitude) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), 0); longitude = CLAMP (longitude, CHAMPLAIN_MIN_LONGITUDE, CHAMPLAIN_MAX_LONGITUDE); /* FIXME: support other projections */ return ((longitude + 180.0) / 360.0 * pow (2.0, zoom_level)) * champlain_map_source_get_tile_size (map_source); }
/** * champlain_map_source_get_y: * @map_source: a #ChamplainMapSource * @zoom_level: the zoom level * @latitude: a latitude * * Gets the y position on the map using this map source's projection. * (0, 0) is located at the top left. * * Returns: the y position * * Since: 0.4 */ gdouble champlain_map_source_get_y (ChamplainMapSource *map_source, guint zoom_level, gdouble latitude) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), 0); latitude = CLAMP (latitude, CHAMPLAIN_MIN_LATITUDE, CHAMPLAIN_MAX_LATITUDE); /* FIXME: support other projections */ return ((1.0 - log (tan (latitude * M_PI / 180.0) + 1.0 / cos (latitude * M_PI / 180.0)) / M_PI) / 2.0 * pow (2.0, zoom_level)) * champlain_map_source_get_tile_size (map_source); }
/** * champlain_map_source_set_next_source: * @map_source: a #ChamplainMapSource * @next_source: the next #ChamplainMapSource in the chain * * Sets the next map source in the chain. * * Since: 0.6 */ void champlain_map_source_set_next_source (ChamplainMapSource *map_source, ChamplainMapSource *next_source) { g_return_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source)); ChamplainMapSourcePrivate *priv = map_source->priv; if (priv->next_source != NULL) g_object_unref (priv->next_source); if (next_source) { g_return_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source)); g_object_ref_sink (next_source); } priv->next_source = next_source; g_object_notify (G_OBJECT (map_source), "next-source"); }
/** * champlain_map_source_get_longitude: * @map_source: a #ChamplainMapSource * @zoom_level: the zoom level * @x: a x position * * Gets the longitude corresponding to this x position in the map source's * projection. * * Returns: the longitude * * Since: 0.4 */ gdouble champlain_map_source_get_longitude (ChamplainMapSource *map_source, guint zoom_level, gdouble x) { gdouble longitude; g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), 0.0); /* FIXME: support other projections */ gdouble dx = (gdouble) x / champlain_map_source_get_tile_size (map_source); longitude = dx / pow (2.0, zoom_level) * 360.0 - 180.0; return CLAMP (longitude, CHAMPLAIN_MIN_LONGITUDE, CHAMPLAIN_MAX_LONGITUDE); }
/** * champlain_map_source_get_latitude: * @map_source: a #ChamplainMapSource * @zoom_level: the zoom level * @y: a y position * * Gets the latitude corresponding to this y position in the map source's * projection. * * Returns: the latitude * * Since: 0.4 */ gdouble champlain_map_source_get_latitude (ChamplainMapSource *map_source, guint zoom_level, gdouble y) { gdouble latitude; g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), 0.0); /* FIXME: support other projections */ gdouble dy = (gdouble) y / champlain_map_source_get_tile_size (map_source); gdouble n = M_PI - 2.0 * M_PI * dy / pow (2.0, zoom_level); latitude = 180.0 / M_PI *atan (0.5 * (exp (n) - exp (-n))); return CLAMP (latitude, CHAMPLAIN_MIN_LATITUDE, CHAMPLAIN_MAX_LATITUDE); }
/** * champlain_map_source_set_renderer: * @map_source: a #ChamplainMapSource * @renderer: the renderer * * Sets the renderer used for tiles rendering. * * Since: 0.8 */ void champlain_map_source_set_renderer (ChamplainMapSource *map_source, ChamplainRenderer *renderer) { g_return_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source)); g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer)); ChamplainMapSourcePrivate *priv = map_source->priv; if (priv->renderer != NULL) g_object_unref (priv->renderer); g_object_ref_sink (renderer); priv->renderer = renderer; g_object_notify (G_OBJECT (map_source), "renderer"); }
/** * champlain_map_source_get_meters_per_pixel: * @map_source: a #ChamplainMapSource * @zoom_level: the zoom level * @latitude: a latitude * @longitude: a longitude * * Gets meters per pixel at the position on the map using this map source's projection. * * Returns: the meters per pixel * * Since: 0.4.3 */ gdouble champlain_map_source_get_meters_per_pixel (ChamplainMapSource *map_source, guint zoom_level, gdouble latitude, G_GNUC_UNUSED gdouble longitude) { g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (map_source), 0.0); /* * Width is in pixels. (1 px) * m/px = radius_at_latitude / width_in_pixels * k = radius of earth = 6 378.1 km * radius_at_latitude = 2pi * k * sin (pi/2-theta) */ gdouble tile_size = champlain_map_source_get_tile_size (map_source); /* FIXME: support other projections */ return 2.0 *M_PI *EARTH_RADIUS *sin (M_PI / 2.0 - M_PI / 180.0 *latitude) / (tile_size * champlain_map_source_get_row_count (map_source, zoom_level)); }
static void fill_tile (ChamplainMapSource *map_source, ChamplainTile *tile) { g_return_if_fail (CHAMPLAIN_IS_FILE_TILE_SOURCE (map_source)); g_return_if_fail (CHAMPLAIN_IS_TILE (tile)); ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source); if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_DONE) return; if (champlain_tile_get_state (tile) != CHAMPLAIN_STATE_LOADED) { ChamplainRenderer *renderer; renderer = champlain_map_source_get_renderer (map_source); g_return_if_fail (CHAMPLAIN_IS_RENDERER (renderer)); g_object_ref (map_source); g_object_ref (tile); g_signal_connect (tile, "render-complete", G_CALLBACK (tile_rendered_cb), map_source); champlain_renderer_render (renderer, tile); } else if (CHAMPLAIN_IS_MAP_SOURCE (next_source)) champlain_map_source_fill_tile (next_source, tile); else if (champlain_tile_get_state (tile) == CHAMPLAIN_STATE_LOADED) { /* if we have some content, use the tile even if it wasn't validated */ champlain_tile_set_state (tile, CHAMPLAIN_STATE_DONE); champlain_tile_display_content (tile); } }