55 |
|
|
56 |
gboolean collision = FALSE; |
gboolean collision = FALSE; |
57 |
tag_t *tags = tag; |
tag_t *tags = tag; |
58 |
|
while(tag) { |
59 |
if(id == ID_ILLEGAL) |
if(!collision && info_tag_key_collision(tags, tag)) |
60 |
str = g_strdup_printf(_("Unknown item")); |
collision = TRUE; |
61 |
else { |
tag = tag->next; |
|
str = g_strdup_printf("%s #" ITEM_ID_FORMAT, item_str, id); |
|
|
|
|
|
/* add some tags ... */ |
|
|
/* |
|
|
* XXX Should we just try to present only the name or the ref (or the |
|
|
* alt_name, old_name, whatever) here? Hurling a load of tags in the |
|
|
* user's face in some unpredictable, uninformative order isn't very |
|
|
* friendly. |
|
|
* |
|
|
* Actually, a tag_short_desc() function would be useful in dialogs |
|
|
* nd user messages too. |
|
|
*/ |
|
|
while(tag) { |
|
|
if(!collision && info_tag_key_collision(tags, tag)) |
|
|
collision = TRUE; |
|
|
|
|
|
/* we don't have much space, so ignore created_by tag */ |
|
|
if(!osm_is_creator_tag(tag)) { |
|
|
char *old = str; |
|
|
str = g_strdup_printf("%s, %s=%s", old, tag->key, tag->value); |
|
|
g_free(old); |
|
|
} |
|
|
tag = tag->next; |
|
|
} |
|
62 |
} |
} |
63 |
|
|
64 |
|
str = osm_object_get_speaking_name(&map_item->object); |
65 |
statusbar_set(map->appdata, str, collision); |
statusbar_set(map->appdata, str, collision); |
66 |
g_free(str); |
g_free(str); |
67 |
} |
} |
144 |
gint h = gdk_pixbuf_get_height(map_item->object.node->icon_buf); |
gint h = gdk_pixbuf_get_height(map_item->object.node->icon_buf); |
145 |
/* icons are technically square, so a radius slightly bigger */ |
/* icons are technically square, so a radius slightly bigger */ |
146 |
/* than sqrt(2)*MAX(w,h) should fit nicely */ |
/* than sqrt(2)*MAX(w,h) should fit nicely */ |
147 |
radius = 0.75 * map->style->icon.scale * ((w>h)?w:h); |
radius = 0.75 * map->style->icon.scale * ((w>h)?w:h); |
148 |
} |
} |
149 |
|
|
150 |
|
radius *= map->state->detail; |
151 |
map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item, |
map_hl_circle_new(map, CANVAS_GROUP_NODES_HL, new_map_item, |
152 |
x, y, radius, map->style->highlight.color); |
x, y, radius, map->style->highlight.color); |
153 |
|
|
176 |
map_statusbar(map, map_item); |
map_statusbar(map, map_item); |
177 |
icon_bar_map_item_selected(appdata, map_item, TRUE); |
icon_bar_map_item_selected(appdata, map_item, TRUE); |
178 |
gtk_widget_set_sensitive(appdata->menu_item_map_hide_sel, TRUE); |
gtk_widget_set_sensitive(appdata->menu_item_map_hide_sel, TRUE); |
179 |
|
|
180 |
gint arrow_width = (map_item->object.way->draw.flags & OSM_DRAW_FLAG_BG)? |
gint arrow_width = ((map_item->object.way->draw.flags & OSM_DRAW_FLAG_BG)? |
181 |
map->style->highlight.width + map_item->object.way->draw.bg.width/2: |
map->style->highlight.width + map_item->object.way->draw.bg.width/2: |
182 |
map->style->highlight.width + map_item->object.way->draw.width/2; |
map->style->highlight.width + map_item->object.way->draw.width/2) |
183 |
|
* map->state->detail; |
184 |
|
|
185 |
node_chain_t *node_chain = map_item->object.way->node_chain; |
node_chain_t *node_chain = map_item->object.way->node_chain; |
186 |
node_t *last = NULL; |
node_t *last = NULL; |
238 |
gint y = node_chain->node->lpos.y; |
gint y = node_chain->node->lpos.y; |
239 |
|
|
240 |
map_hl_circle_new(map, CANVAS_GROUP_NODES_IHL, new_map_item, |
map_hl_circle_new(map, CANVAS_GROUP_NODES_IHL, new_map_item, |
241 |
x, y, map->style->node.radius, |
x, y, map->style->node.radius * map->state->detail, |
242 |
map->style->highlight.node_color); |
map->style->highlight.node_color); |
243 |
} |
} |
244 |
|
|
266 |
new_map_item->highlight = TRUE; |
new_map_item->highlight = TRUE; |
267 |
|
|
268 |
map_hl_polyline_new(map, CANVAS_GROUP_WAYS_HL, new_map_item, points, |
map_hl_polyline_new(map, CANVAS_GROUP_WAYS_HL, new_map_item, points, |
269 |
(map_item->object.way->draw.flags & OSM_DRAW_FLAG_BG)? |
((map_item->object.way->draw.flags & OSM_DRAW_FLAG_BG)? |
270 |
2*map->style->highlight.width + map_item->object.way->draw.bg.width: |
2*map->style->highlight.width + map_item->object.way->draw.bg.width: |
271 |
2*map->style->highlight.width + map_item->object.way->draw.width, |
2*map->style->highlight.width + map_item->object.way->draw.width) |
272 |
map->style->highlight.color); |
* map->state->detail, map->style->highlight.color); |
273 |
|
|
274 |
canvas_points_free(points); |
canvas_points_free(points); |
275 |
} |
} |
276 |
} |
} |
379 |
osm_tags_free(appdata->map->last_node_tags); |
osm_tags_free(appdata->map->last_node_tags); |
380 |
|
|
381 |
appdata->map->last_node_tags = |
appdata->map->last_node_tags = |
382 |
osm_tags_copy(appdata->map->selected.object.node->tag, FALSE); |
osm_tags_copy(appdata->map->selected.object.node->tag); |
383 |
} else if(appdata->map->selected.object.type == WAY) { |
} else if(appdata->map->selected.object.type == WAY) { |
384 |
if(appdata->map->last_way_tags) |
if(appdata->map->last_way_tags) |
385 |
osm_tags_free(appdata->map->last_way_tags); |
osm_tags_free(appdata->map->last_way_tags); |
386 |
|
|
387 |
appdata->map->last_way_tags = |
appdata->map->last_way_tags = |
388 |
osm_tags_copy(appdata->map->selected.object.way->tag, FALSE); |
osm_tags_copy(appdata->map->selected.object.way->tag); |
389 |
} |
} |
390 |
|
|
391 |
/* remove statusbar message */ |
/* remove statusbar message */ |
451 |
else |
else |
452 |
map_item->item = canvas_image_new(map->canvas, CANVAS_GROUP_NODES, |
map_item->item = canvas_image_new(map->canvas, CANVAS_GROUP_NODES, |
453 |
node->icon_buf, |
node->icon_buf, |
454 |
node->lpos.x - map->style->icon.scale/2 * |
node->lpos.x - map->style->icon.scale/2 * map->state->detail * |
455 |
gdk_pixbuf_get_width(node->icon_buf), |
gdk_pixbuf_get_width(node->icon_buf), |
456 |
node->lpos.y - map->style->icon.scale/2 * |
node->lpos.y - map->style->icon.scale/2 * map->state->detail * |
457 |
gdk_pixbuf_get_height(node->icon_buf), |
gdk_pixbuf_get_height(node->icon_buf), |
458 |
map->style->icon.scale,map->style->icon.scale); |
map->state->detail * map->style->icon.scale, |
459 |
|
map->state->detail * map->style->icon.scale); |
460 |
|
|
461 |
canvas_item_set_zoom_max(map_item->item, node->zoom_max); |
canvas_item_set_zoom_max(map_item->item, |
462 |
|
node->zoom_max / (2 * map->state->detail)); |
463 |
|
|
464 |
/* attach map_item to nodes map_item_chain */ |
/* attach map_item to nodes map_item_chain */ |
465 |
map_item_chain_t **chain = &node->map_item_chain; |
map_item_chain_t **chain = &node->map_item_chain; |
521 |
map_item->item = canvas_polyline_new(map->canvas, group, points, width, color); |
map_item->item = canvas_polyline_new(map->canvas, group, points, width, color); |
522 |
} |
} |
523 |
|
|
524 |
canvas_item_set_zoom_max(map_item->item, way->draw.zoom_max); |
canvas_item_set_zoom_max(map_item->item, |
525 |
|
way->draw.zoom_max / (2 * map->state->detail)); |
526 |
|
|
527 |
/* a ways outline itself is never dashed */ |
/* a ways outline itself is never dashed */ |
528 |
if (group != CANVAS_GROUP_WAYS_OL) |
if (group != CANVAS_GROUP_WAYS_OL) |
572 |
} |
} |
573 |
|
|
574 |
/* draw way */ |
/* draw way */ |
575 |
|
float width = way->draw.width * map->state->detail; |
576 |
|
|
577 |
if(way->draw.flags & OSM_DRAW_FLAG_AREA) { |
if(way->draw.flags & OSM_DRAW_FLAG_AREA) { |
578 |
map_way_new(map, CANVAS_GROUP_POLYGONS, way, points, |
map_way_new(map, CANVAS_GROUP_POLYGONS, way, points, |
579 |
way->draw.width, way->draw.color, way->draw.area.color); |
width, way->draw.color, way->draw.area.color); |
580 |
} else { |
} else { |
581 |
|
|
582 |
if(way->draw.flags & OSM_DRAW_FLAG_BG) { |
if(way->draw.flags & OSM_DRAW_FLAG_BG) { |
583 |
map_way_new(map, CANVAS_GROUP_WAYS_INT, way, points, |
map_way_new(map, CANVAS_GROUP_WAYS_INT, way, points, |
584 |
way->draw.width, way->draw.color, NO_COLOR); |
width, way->draw.color, NO_COLOR); |
585 |
|
|
586 |
map_way_new(map, CANVAS_GROUP_WAYS_OL, way, points, |
map_way_new(map, CANVAS_GROUP_WAYS_OL, way, points, |
587 |
way->draw.bg.width, way->draw.bg.color, NO_COLOR); |
way->draw.bg.width * map->state->detail, |
588 |
|
way->draw.bg.color, NO_COLOR); |
589 |
|
|
590 |
} else |
} else |
591 |
map_way_new(map, CANVAS_GROUP_WAYS, way, points, |
map_way_new(map, CANVAS_GROUP_WAYS, way, points, |
592 |
way->draw.width, way->draw.color, NO_COLOR); |
width, way->draw.color, NO_COLOR); |
593 |
} |
} |
594 |
canvas_points_free(points); |
canvas_points_free(points); |
595 |
} |
} |
602 |
|
|
603 |
if(!node->ways) |
if(!node->ways) |
604 |
map_node_new(map, node, |
map_node_new(map, node, |
605 |
map->style->node.radius, |
map->style->node.radius * map->state->detail, |
606 |
map->style->node.border_radius, |
map->style->node.border_radius * map->state->detail, |
607 |
map->style->node.fill_color, |
map->style->node.fill_color, |
608 |
map->style->node.color); |
map->style->node.color); |
609 |
|
|
610 |
else if(map->style->node.show_untagged || osm_node_has_tag(node)) |
else if(map->style->node.show_untagged || osm_node_has_tag(node)) |
611 |
map_node_new(map, node, |
map_node_new(map, node, |
612 |
map->style->node.radius, 0, |
map->style->node.radius * map->state->detail, 0, |
613 |
map->style->node.color, 0); |
map->style->node.color, 0); |
614 |
} |
} |
615 |
|
|
662 |
void map_item_redraw(appdata_t *appdata, map_item_t *map_item) { |
void map_item_redraw(appdata_t *appdata, map_item_t *map_item) { |
663 |
map_item_t item = *map_item; |
map_item_t item = *map_item; |
664 |
|
|
665 |
|
/* a relation cannot be redraws as it doesn't have a visual */ |
666 |
|
/* representation */ |
667 |
|
if(map_item->object.type == RELATION) |
668 |
|
return; |
669 |
|
|
670 |
/* check if the item to be redrawn is the selected one */ |
/* check if the item to be redrawn is the selected one */ |
671 |
gboolean is_selected = FALSE; |
gboolean is_selected = FALSE; |
672 |
if(map_item->object.ptr == appdata->map->selected.object.ptr) { |
if(map_item->object.ptr == appdata->map->selected.object.ptr) { |
997 |
} |
} |
998 |
} |
} |
999 |
if (*zoom != oldzoom) { |
if (*zoom != oldzoom) { |
1000 |
printf("Can't zoom further out\n"); |
printf("Can't zoom further out (%f)\n", *zoom); |
1001 |
return 1; |
return 1; |
1002 |
} |
} |
1003 |
return 0; |
return 0; |
1356 |
/* don't highlight the dragged node itself and don't highlight */ |
/* don't highlight the dragged node itself and don't highlight */ |
1357 |
/* deleted ones */ |
/* deleted ones */ |
1358 |
if((node != cur_node) && (!(node->flags & OSM_FLAG_DELETED))) { |
if((node != cur_node) && (!(node->flags & OSM_FLAG_DELETED))) { |
1359 |
gint nx = x - node->lpos.x; |
gint nx = abs(x - node->lpos.x); |
1360 |
gint ny = y - node->lpos.y; |
gint ny = abs(y - node->lpos.y); |
1361 |
|
|
1362 |
if((nx < map->style->node.radius) && (ny < map->style->node.radius) && |
if((nx < map->style->node.radius) && (ny < map->style->node.radius) && |
1363 |
(nx*nx + ny*ny < map->style->node.radius * map->style->node.radius)) |
(nx*nx + ny*ny < map->style->node.radius * map->style->node.radius)) |
1371 |
if(!map->touchnode && map->action.way) { |
if(!map->touchnode && map->action.way) { |
1372 |
node_chain_t *chain = map->action.way->node_chain; |
node_chain_t *chain = map->action.way->node_chain; |
1373 |
while(!map->touchnode && chain && chain->next) { |
while(!map->touchnode && chain && chain->next) { |
1374 |
gint nx = x - chain->node->lpos.x; |
gint nx = abs(x - chain->node->lpos.x); |
1375 |
gint ny = y - chain->node->lpos.y; |
gint ny = abs(y - chain->node->lpos.y); |
1376 |
|
|
1377 |
if((nx < map->style->node.radius) && (ny < map->style->node.radius) && |
if((nx < map->style->node.radius) && (ny < map->style->node.radius) && |
1378 |
(nx*nx + ny*ny < map->style->node.radius * map->style->node.radius)) |
(nx*nx + ny*ny < map->style->node.radius * map->style->node.radius)) |
1730 |
return FALSE; |
return FALSE; |
1731 |
} |
} |
1732 |
|
|
1733 |
|
void map_state_reset(map_state_t *state) { |
1734 |
|
if(!state) return; |
1735 |
|
|
1736 |
|
state->zoom = 0.25; |
1737 |
|
state->detail = 1.0; |
1738 |
|
|
1739 |
|
/* todo: try to scroll to center of screen */ |
1740 |
|
state->scroll_offset.x = 0; |
1741 |
|
state->scroll_offset.y = 0; |
1742 |
|
} |
1743 |
|
|
1744 |
|
map_state_t *map_state_new(void) { |
1745 |
|
map_state_t *state = g_new0(map_state_t, 1); |
1746 |
|
map_state_reset(state); |
1747 |
|
return state; |
1748 |
|
} |
1749 |
|
|
1750 |
GtkWidget *map_new(appdata_t *appdata) { |
GtkWidget *map_new(appdata_t *appdata) { |
1751 |
map_t *map = appdata->map = g_new0(map_t, 1); |
map_t *map = appdata->map = g_new0(map_t, 1); |
1752 |
|
|
1762 |
map->state = appdata->project->map_state; |
map->state = appdata->project->map_state; |
1763 |
} else { |
} else { |
1764 |
printf("Creating new map state\n"); |
printf("Creating new map state\n"); |
1765 |
map->state = g_new0(map_state_t, 1); |
map->state = map_state_new(); |
|
map->state->zoom = 0.25; |
|
1766 |
} |
} |
1767 |
|
|
1768 |
map->state->refcount++; |
map->state->refcount++; |
1772 |
map->appdata = appdata; |
map->appdata = appdata; |
1773 |
map->action.type = MAP_ACTION_IDLE; |
map->action.type = MAP_ACTION_IDLE; |
1774 |
|
|
1775 |
map->canvas = canvas_new(map->style->background.color); |
map->canvas = canvas_new(); |
|
canvas_set_antialias(map->canvas, !appdata->settings->no_antialias); |
|
1776 |
|
|
1777 |
GtkWidget *canvas_widget = canvas_get_widget(map->canvas); |
GtkWidget *canvas_widget = canvas_get_widget(map->canvas); |
1778 |
|
|
1801 |
void map_init(appdata_t *appdata) { |
void map_init(appdata_t *appdata) { |
1802 |
map_t *map = appdata->map; |
map_t *map = appdata->map; |
1803 |
|
|
1804 |
|
/* update canvas background color */ |
1805 |
|
canvas_set_background(map->canvas, map->style->background.color); |
1806 |
|
|
1807 |
/* set initial zoom */ |
/* set initial zoom */ |
1808 |
map_set_zoom(map, map->state->zoom, FALSE); |
map_set_zoom(map, map->state->zoom, FALSE); |
1809 |
josm_elemstyles_colorize_world(map->style, appdata->osm); |
josm_elemstyles_colorize_world(map->style, appdata->osm); |
1843 |
void map_paint(appdata_t *appdata) { |
void map_paint(appdata_t *appdata) { |
1844 |
map_t *map = appdata->map; |
map_t *map = appdata->map; |
1845 |
|
|
|
/* user may have changed antialias settings */ |
|
|
canvas_set_antialias(map->canvas, !appdata->settings->no_antialias); |
|
|
|
|
1846 |
josm_elemstyles_colorize_world(map->style, appdata->osm); |
josm_elemstyles_colorize_world(map->style, appdata->osm); |
1847 |
map_draw(map, appdata->osm); |
map_draw(map, appdata->osm); |
1848 |
} |
} |
1950 |
/* save changes to bg_offset in project */ |
/* save changes to bg_offset in project */ |
1951 |
appdata->project->wms_offset.x = map->bg.offset.x; |
appdata->project->wms_offset.x = map->bg.offset.x; |
1952 |
appdata->project->wms_offset.y = map->bg.offset.y; |
appdata->project->wms_offset.y = map->bg.offset.y; |
|
appdata->project->dirty = TRUE; |
|
1953 |
break; |
break; |
1954 |
|
|
1955 |
default: |
default: |
2376 |
gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE); |
gtk_widget_set_sensitive(appdata->menu_item_map_show_all, FALSE); |
2377 |
} |
} |
2378 |
|
|
2379 |
|
static void map_detail_change(map_t *map, float detail) { |
2380 |
|
appdata_t *appdata = map->appdata; |
2381 |
|
|
2382 |
|
/* deselecting anything allows us not to care about automatic deselection */ |
2383 |
|
/* as well as items becoming invisible by the detail change */ |
2384 |
|
map_item_deselect(appdata); |
2385 |
|
|
2386 |
|
map->state->detail = detail; |
2387 |
|
printf("changing detail factor to %f\n", map->state->detail); |
2388 |
|
|
2389 |
|
banner_busy_start(appdata, 1, _("Redrawing")); |
2390 |
|
map_clear(appdata, MAP_LAYER_OBJECTS_ONLY); |
2391 |
|
map_paint(appdata); |
2392 |
|
banner_busy_stop(appdata); |
2393 |
|
} |
2394 |
|
|
2395 |
|
#define DETAIL_STEP 1.5 |
2396 |
|
|
2397 |
|
void map_detail_increase(map_t *map) { |
2398 |
|
if(!map) return; |
2399 |
|
map_detail_change(map, map->state->detail * DETAIL_STEP); |
2400 |
|
} |
2401 |
|
|
2402 |
|
void map_detail_decrease(map_t *map) { |
2403 |
|
if(!map) return; |
2404 |
|
map_detail_change(map, map->state->detail / DETAIL_STEP); |
2405 |
|
} |
2406 |
|
|
2407 |
|
void map_detail_normal(map_t *map) { |
2408 |
|
if(!map) return; |
2409 |
|
map_detail_change(map, 1.0); |
2410 |
|
} |
2411 |
|
|
2412 |
// vim:et:ts=8:sw=2:sts=2:ai |
// vim:et:ts=8:sw=2:sts=2:ai |