17 |
* along with OSM2Go. If not, see <http://www.gnu.org/licenses/>. |
* along with OSM2Go. If not, see <http://www.gnu.org/licenses/>. |
18 |
*/ |
*/ |
19 |
|
|
20 |
|
/* |
21 |
|
http://josm.openstreetmap.de/svn/trunk/styles/standard/elemstyles.xml |
22 |
|
*/ |
23 |
|
|
24 |
#include "appdata.h" |
#include "appdata.h" |
25 |
|
|
26 |
#include <libxml/parser.h> |
#include <libxml/parser.h> |
126 |
return line; |
return line; |
127 |
} |
} |
128 |
|
|
129 |
|
/* parse "+123", "-123" and "123%" */ |
130 |
|
static void parse_width_mod(xmlNode *a_node, char *name, |
131 |
|
elemstyle_width_mod_t *value) { |
132 |
|
char *mod_str = (char*)xmlGetProp(a_node, BAD_CAST name); |
133 |
|
if(mod_str && strlen(mod_str) > 0) { |
134 |
|
if(mod_str[0] == '+') { |
135 |
|
value->mod = ES_MOD_ADD; |
136 |
|
value->width = strtoul(mod_str+1, NULL, 10); |
137 |
|
} else if(mod_str[0] == '-') { |
138 |
|
value->mod = ES_MOD_SUB; |
139 |
|
value->width = strtoul(mod_str+1, NULL, 10); |
140 |
|
} else if(mod_str[strlen(mod_str)-1] == '%') { |
141 |
|
value->mod = ES_MOD_PERCENT; |
142 |
|
value->width = strtoul(mod_str, NULL, 10); |
143 |
|
} else |
144 |
|
printf("warning: unable to parse modifier %s\n", mod_str); |
145 |
|
} |
146 |
|
} |
147 |
|
|
148 |
|
static elemstyle_line_mod_t *parse_line_mod(xmlDocPtr doc, xmlNode *a_node) { |
149 |
|
elemstyle_line_mod_t *line_mod = g_new0(elemstyle_line_mod_t, 1); |
150 |
|
|
151 |
|
parse_width_mod(a_node, "width", &line_mod->line); |
152 |
|
parse_width_mod(a_node, "width_bg", &line_mod->bg); |
153 |
|
|
154 |
|
return line_mod; |
155 |
|
} |
156 |
|
|
157 |
static elemstyle_area_t *parse_area(xmlDocPtr doc, xmlNode *a_node) { |
static elemstyle_area_t *parse_area(xmlDocPtr doc, xmlNode *a_node) { |
158 |
elemstyle_area_t *area = g_new0(elemstyle_area_t, 1); |
elemstyle_area_t *area = g_new0(elemstyle_area_t, 1); |
159 |
|
|
191 |
/* ------ parse condition ------ */ |
/* ------ parse condition ------ */ |
192 |
elemstyle->condition.key = (char*)xmlGetProp(cur_node, BAD_CAST "k"); |
elemstyle->condition.key = (char*)xmlGetProp(cur_node, BAD_CAST "k"); |
193 |
elemstyle->condition.value = (char*)xmlGetProp(cur_node, BAD_CAST "v"); |
elemstyle->condition.value = (char*)xmlGetProp(cur_node, BAD_CAST "v"); |
194 |
|
/* todo: add support for "b" (boolean) value */ |
195 |
} else if(strcasecmp((char*)cur_node->name, "line") == 0) { |
} else if(strcasecmp((char*)cur_node->name, "line") == 0) { |
196 |
/* ------ parse line ------ */ |
/* ------ parse line ------ */ |
197 |
g_assert(elemstyle->type == ES_TYPE_NONE); |
g_assert(elemstyle->type == ES_TYPE_NONE); |
198 |
elemstyle->type = ES_TYPE_LINE; |
elemstyle->type = ES_TYPE_LINE; |
199 |
elemstyle->line = parse_line(doc, cur_node); |
elemstyle->line = parse_line(doc, cur_node); |
200 |
|
} else if(strcasecmp((char*)cur_node->name, "linemod") == 0) { |
201 |
|
/* ------ parse linemod ------ */ |
202 |
|
g_assert(elemstyle->type == ES_TYPE_NONE); |
203 |
|
elemstyle->type = ES_TYPE_LINE_MOD; |
204 |
|
elemstyle->line_mod = parse_line_mod(doc, cur_node); |
205 |
} else if(strcasecmp((char*)cur_node->name, "area") == 0) { |
} else if(strcasecmp((char*)cur_node->name, "area") == 0) { |
206 |
/* ------ parse area ------ */ |
/* ------ parse area ------ */ |
207 |
g_assert(elemstyle->type == ES_TYPE_NONE); |
g_assert(elemstyle->type == ES_TYPE_NONE); |
224 |
parse_scale_max(cur_node, &elemstyle->icon->zoom_max); |
parse_scale_max(cur_node, &elemstyle->icon->zoom_max); |
225 |
} |
} |
226 |
else { |
else { |
227 |
printf("scale_max for unhandled elemstyletype=0x02%x\n", elemstyle->type); |
printf("scale_max for unhandled elemstyletype=0x02%x\n", |
228 |
|
elemstyle->type); |
229 |
} |
} |
230 |
break; |
break; |
231 |
} |
} |
309 |
g_free(line); |
g_free(line); |
310 |
} |
} |
311 |
|
|
312 |
|
static void free_line_mod(elemstyle_line_mod_t *line_mod) { |
313 |
|
g_free(line_mod); |
314 |
|
} |
315 |
|
|
316 |
static void free_area(elemstyle_area_t *area) { |
static void free_area(elemstyle_area_t *area) { |
317 |
g_free(area); |
g_free(area); |
318 |
} |
} |
335 |
case ES_TYPE_AREA: |
case ES_TYPE_AREA: |
336 |
free_area(elemstyle->area); |
free_area(elemstyle->area); |
337 |
break; |
break; |
338 |
|
case ES_TYPE_LINE_MOD: |
339 |
|
free_line_mod(elemstyle->line_mod); |
340 |
|
break; |
341 |
} |
} |
342 |
if(elemstyle->icon) free_icon(elemstyle->icon); |
if(elemstyle->icon) free_icon(elemstyle->icon); |
343 |
g_free(elemstyle); |
g_free(elemstyle); |
395 |
} |
} |
396 |
} |
} |
397 |
|
|
398 |
|
static void line_mod_apply(gint *width, elemstyle_width_mod_t *mod) { |
399 |
|
switch(mod->mod) { |
400 |
|
case ES_MOD_NONE: |
401 |
|
break; |
402 |
|
|
403 |
|
case ES_MOD_ADD: |
404 |
|
*width += mod->width; |
405 |
|
break; |
406 |
|
|
407 |
|
case ES_MOD_SUB: |
408 |
|
*width -= mod->width; |
409 |
|
break; |
410 |
|
|
411 |
|
case ES_MOD_PERCENT: |
412 |
|
*width = 100 * *width / mod->width; |
413 |
|
break; |
414 |
|
} |
415 |
|
} |
416 |
|
|
417 |
void josm_elemstyles_colorize_way(style_t *style, way_t *way) { |
void josm_elemstyles_colorize_way(style_t *style, way_t *way) { |
418 |
elemstyle_t *elemstyle = style->elemstyles; |
elemstyle_t *elemstyle = style->elemstyles; |
419 |
|
|
423 |
way->draw.flags = 0; |
way->draw.flags = 0; |
424 |
way->draw.zoom_max = 0; // draw at all zoom levels |
way->draw.zoom_max = 0; // draw at all zoom levels |
425 |
|
|
426 |
|
/* during the elemstyle search a line_mod may be found. save it here */ |
427 |
|
elemstyle_line_mod_t *line_mod = NULL; |
428 |
|
|
429 |
|
gboolean way_processed = FALSE; |
430 |
gboolean way_is_closed = |
gboolean way_is_closed = |
431 |
(osm_way_get_last_node(way) == osm_way_get_first_node(way)); |
(osm_way_get_last_node(way) == osm_way_get_first_node(way)); |
432 |
|
|
458 |
break; |
break; |
459 |
|
|
460 |
case ES_TYPE_LINE: |
case ES_TYPE_LINE: |
461 |
way->draw.color = (elemstyle->line->color << 8) | 0xff; |
if(!way_processed) { |
462 |
way->draw.width = WIDTH_SCALE * elemstyle->line->width; |
way->draw.color = (elemstyle->line->color << 8) | 0xff; |
463 |
if(elemstyle->line->bg.valid) { |
way->draw.width = WIDTH_SCALE * elemstyle->line->width; |
464 |
way->draw.flags |= OSM_DRAW_FLAG_BG; |
if(elemstyle->line->bg.valid) { |
465 |
way->draw.bg.color = (elemstyle->line->bg.color << 8) | 0xff; |
way->draw.flags |= OSM_DRAW_FLAG_BG; |
466 |
way->draw.bg.width = WIDTH_SCALE * elemstyle->line->bg.width; |
way->draw.bg.color = (elemstyle->line->bg.color << 8) | 0xff; |
467 |
} |
way->draw.bg.width = WIDTH_SCALE * elemstyle->line->bg.width; |
468 |
if (elemstyle->line->zoom_max > 0) { |
} |
469 |
way->draw.zoom_max = elemstyle->line->zoom_max; |
if (elemstyle->line->zoom_max > 0) { |
470 |
} |
way->draw.zoom_max = elemstyle->line->zoom_max; |
471 |
else { |
} |
472 |
way->draw.zoom_max = style->way.zoom_max; |
else { |
473 |
|
way->draw.zoom_max = style->way.zoom_max; |
474 |
|
} |
475 |
|
way->draw.dashed = elemstyle->line->dashed; |
476 |
|
way_processed = TRUE; |
477 |
} |
} |
478 |
way->draw.dashed = elemstyle->line->dashed; |
break; |
479 |
return; |
|
480 |
|
case ES_TYPE_LINE_MOD: |
481 |
|
/* just save the fact that a line mod was found for later */ |
482 |
|
line_mod = elemstyle->line_mod; |
483 |
break; |
break; |
484 |
|
|
485 |
case ES_TYPE_AREA: |
case ES_TYPE_AREA: |
486 |
if(way_is_closed) { |
if(way_is_closed && !way_processed) { |
487 |
way->draw.flags |= OSM_DRAW_FLAG_AREA; |
way->draw.flags |= OSM_DRAW_FLAG_AREA; |
488 |
/* comment the following line for grey border around all areas */ |
/* comment the following line for grey border around all areas */ |
489 |
/* (potlatch style) */ |
/* (potlatch style) */ |
502 |
else { |
else { |
503 |
way->draw.zoom_max = style->area.zoom_max; |
way->draw.zoom_max = style->area.zoom_max; |
504 |
} |
} |
505 |
return; |
way_processed = TRUE; |
506 |
} |
} |
507 |
break; |
break; |
508 |
} |
} |
509 |
} |
} |
510 |
elemstyle = elemstyle->next; |
elemstyle = elemstyle->next; |
511 |
} |
} |
512 |
|
|
513 |
|
/* apply the last line mod entry that has been found during search */ |
514 |
|
if(line_mod) { |
515 |
|
printf("applying last matching line mod to way #%ld\n", way->id); |
516 |
|
line_mod_apply(&way->draw.width, &line_mod->line); |
517 |
|
|
518 |
|
/* special case: the way does not have a background, but it is to */ |
519 |
|
/* be modified */ |
520 |
|
if((line_mod->bg.mod != ES_MOD_NONE) && |
521 |
|
(!(way->draw.flags & OSM_DRAW_FLAG_BG))) { |
522 |
|
printf("forcing background\n"); |
523 |
|
|
524 |
|
/* add a background in black color */ |
525 |
|
way->draw.flags |= OSM_DRAW_FLAG_BG; |
526 |
|
way->draw.bg.color = (0) | 0xff; |
527 |
|
way->draw.bg.width = way->draw.width; |
528 |
|
} |
529 |
|
|
530 |
|
line_mod_apply(&way->draw.bg.width, &line_mod->bg); |
531 |
|
} |
532 |
} |
} |
533 |
|
|
534 |
void josm_elemstyles_colorize_world(style_t *styles, osm_t *osm) { |
void josm_elemstyles_colorize_world(style_t *styles, osm_t *osm) { |