summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wildemann <metalstrolch@users.noreply.github.com>2022-01-01 14:12:44 +0100
committerGitHub <noreply@github.com>2022-01-01 14:12:44 +0100
commit17f1a6ec6aebbc51a67be6ac6064d231ce02a62e (patch)
treeade88ff515cba3763fc9ac00ec2f0a392ec32ba5
parent13e550f93052ef6d51fcbde76cd6796a3cc6bb4e (diff)
downloadnavit-17f1a6ec6aebbc51a67be6ac6064d231ce02a62e.tar.gz
feature: graphics: allow spiked lines for cliff and embarkments (#1174)
* feature: graphics: allow spiked lines for cliff and embarkments This adds another drwing element to graphics system. It can produce lines with spikes as used for cliffs on maps. Additionally this adds embarlment support for map. * review fixes. Add changes requested by review, plus add paranoia check on xml parameter.
-rw-r--r--navit/attr.h1
-rw-r--r--navit/attr_def.h2
-rw-r--r--navit/graphics.c67
-rw-r--r--navit/item_def.h1
-rw-r--r--navit/layout.c33
-rw-r--r--navit/layout.h7
-rw-r--r--navit/maptool/osm.c1
-rw-r--r--navit/navit.dtd6
-rw-r--r--navit/navit_layout_car_shipped.xml10
-rw-r--r--navit/xmlconfig.c8
10 files changed, 132 insertions, 4 deletions
diff --git a/navit/attr.h b/navit/attr.h
index a49f033fe..cae591ffd 100644
--- a/navit/attr.h
+++ b/navit/attr.h
@@ -192,6 +192,7 @@ struct attr {
struct icon *icon;
struct image *image;
struct arrows *arrows;
+ struct spikes *spikes;
struct element *element;
struct speech *speech;
struct cursor *cursor;
diff --git a/navit/attr_def.h b/navit/attr_def.h
index 951b57060..a2863edea 100644
--- a/navit/attr_def.h
+++ b/navit/attr_def.h
@@ -204,6 +204,7 @@ ATTR(virtual_dpi)
ATTR(real_dpi)
ATTR(underground_alpha)
ATTR(sunrise_degrees)
+ATTR(distance)
ATTR2(0x00027500,type_rel_abs_begin)
/* These attributes are int that can either hold relative or absolute values. See the
* documentation of ATTR_REL_RELSHIFT for details.
@@ -495,6 +496,7 @@ ATTR(layout)
ATTR(profile_option)
ATTR(script)
ATTR(traffic)
+ATTR(spikes)
ATTR2(0x0008ffff,type_object_end)
ATTR2(0x00090000,type_coord_begin)
ATTR2(0x0009ffff,type_coord_end)
diff --git a/navit/graphics.c b/navit/graphics.c
index aabe9b7bc..08de16a1e 100644
--- a/navit/graphics.c
+++ b/navit/graphics.c
@@ -1720,6 +1720,67 @@ static void display_draw_arrows(struct graphics *gra, struct display_context *dc
}
}
+static void display_draw_spike(struct point *p, navit_float dx, navit_float dy, navit_float width,
+ struct display_context *dc,
+ struct graphics *gra) {
+ struct point pnt[2];
+ navit_float l=navit_sqrt(dx*dx+dy*dy);
+ pnt[0]=pnt[1]=*p;
+ pnt[1].x+=(-dy/l)*width;
+ pnt[1].y+=(dx/l)*width;
+ graphics_draw_lines(gra, dc->gc, pnt, 2);
+}
+
+/**
+ * @brief draw spikes along a multi polygon line
+ *
+ * This function draws spikes along a multi polygon line, and scales the
+ * spikes according to current view settings by interpolating sizes at
+ * given spike position,
+ *
+ * @param gra current graphics instance handle
+ * @param dc current drawing context
+ * @param pnt array of points for this polyline
+ * @param count number of points in pnt
+ * @param width array of integers giving the expected line width at the corresponding point
+ * @param distance giving the distance between spikes
+ */
+static void display_draw_spikes(struct graphics *gra, struct display_context *dc, struct point *pnt, int count,
+ int *width, int distance) {
+ navit_float dx,dy,dw,l;
+ int i;
+ struct point p;
+ int w;
+ for (i = 0 ; i < count-1 ; i++) {
+ /* get the X and Y size */
+ dx=pnt[i+1].x-pnt[i].x;
+ dy=pnt[i+1].y-pnt[i].y;
+ dw=width[i+1] - width[i];
+ /* calculate the length of the way segment */
+ l=navit_sqrt(dx*dx+dy*dy);
+ if (l != 0) {
+ /* length is not zero */
+ if(l > width[i]) {
+ /* length is bigger than the length of one spike */
+ int a;
+ int spike_count = l / distance;
+ /* calculate the vector per spike */
+ dx=dx/spike_count;
+ dy=dy/spike_count;
+ dw=dw/spike_count;
+ for( a=0; a < spike_count; a++ ) {
+ p=pnt[i];
+ p.x+=dx*a;
+ p.y+=dy*a;
+ w=width[i];
+ w+=dw*a;
+ display_draw_spike(&p, dx, dy, w, dc, gra);
+ }
+ }
+ }
+ }
+}
+
static int intersection(struct point * a1, int adx, int ady, struct point * b1, int bdx, int bdy, struct point * res) {
int n, a, b;
dbg(lvl_debug,"%d,%d - %d,%d x %d,%d-%d,%d",a1->x,a1->y,a1->x+adx,a1->y+ady,b1->x,b1->y,b1->x+bdx,b1->y+bdy);
@@ -2954,6 +3015,9 @@ static void displayitem_draw(struct displayitem *di, struct layout *l, struct di
else if (dc->e->type == element_arrows)
count=transform_point_buf(dc->trans, dc->pro, di->c, pa, pa_buf_size, count, mindist, e->u.arrows.width,
width);
+ else if (dc->e->type == element_spikes)
+ count=transform_point_buf(dc->trans, dc->pro, di->c, pa, pa_buf_size, count, mindist, e->u.spikes.width,
+ width);
else
count=transform_point_buf(dc->trans, dc->pro, di->c, pa, pa_buf_size, count, mindist, 0, NULL);
switch (e->type) {
@@ -2978,6 +3042,9 @@ static void displayitem_draw(struct displayitem *di, struct layout *l, struct di
case element_arrows:
display_draw_arrows(gra,dc,pa,count, width, e->oneway);
break;
+ case element_spikes:
+ display_draw_spikes(gra,dc,pa,count, width, e->u.spikes.distance);
+ break;
default:
dbg(lvl_error, "Unhandled element type %d", e->type);
diff --git a/navit/item_def.h b/navit/item_def.h
index 82f49d2a0..ae716e7c8 100644
--- a/navit/item_def.h
+++ b/navit/item_def.h
@@ -529,6 +529,7 @@ ITEM(former_itinerary_part)
ITEM(cliff)
ITEM(sports_track)
ITEM(archaeological_site)
+ITEM(embankment)
/* Area */
ITEM2(0xc0000000,area)
ITEM2(0xc0000001,area_unspecified)
diff --git a/navit/layout.c b/navit/layout.c
index 0889fb52b..2300ab68d 100644
--- a/navit/layout.c
+++ b/navit/layout.c
@@ -399,6 +399,7 @@ int itemgra_add_attr(struct itemgra *itemgra, struct attr *attr) {
case attr_icon:
case attr_image:
case attr_arrows:
+ case attr_spikes:
itemgra->elements = g_list_append(itemgra->elements, attr->u.element);
return 1;
default:
@@ -446,6 +447,27 @@ static void element_set_arrows_width(struct element *e, struct attr **attrs) {
e->u.arrows.width=10;
}
+static void element_set_spikes_width(struct element *e, struct attr **attrs) {
+ struct attr *width;
+ width=attr_search(attrs, attr_width);
+ if (width)
+ e->u.spikes.width=width->u.num;
+ else
+ e->u.spikes.width=10;
+}
+
+static void element_set_spikes_distance(struct element *e, struct attr **attrs) {
+ struct attr *distance;
+ distance=attr_search(attrs, attr_distance);
+ if (distance) {
+ e->u.spikes.distance=distance->u.num;
+ /* paranoia check. We divide with that value */
+ if(e->u.spikes.distance < 1)
+ e->u.spikes.distance = 1;
+ } else
+ e->u.spikes.distance=10;
+}
+
static void element_set_polyline_width(struct element *e, struct attr **attrs) {
struct attr *width;
width=attr_search(attrs, attr_width);
@@ -651,6 +673,17 @@ arrows_new(struct attr *parent, struct attr **attrs) {
return (struct arrows *)e;
}
+struct spikes *
+spikes_new(struct attr *parent, struct attr **attrs) {
+ struct element *e;
+ e = g_malloc0(sizeof(*e));
+ e->type=element_spikes;
+ element_set_color(e, attrs);
+ element_set_spikes_width(e, attrs);
+ element_set_spikes_distance(e, attrs);
+ return (struct spikes *)e;
+}
+
int element_add_attr(struct element *e, struct attr *attr) {
switch (attr->type) {
case attr_coord:
diff --git a/navit/layout.h b/navit/layout.h
index 47b078ab1..210519a83 100644
--- a/navit/layout.h
+++ b/navit/layout.h
@@ -34,7 +34,7 @@ struct poly_hole {
};
struct element {
- enum { element_point, element_polyline, element_polygon, element_circle, element_text, element_icon, element_image, element_arrows } type;
+ enum { element_point, element_polyline, element_polygon, element_circle, element_text, element_icon, element_image, element_arrows, element_spikes } type;
struct color color;
int text_size;
int oneway;
@@ -77,6 +77,10 @@ struct element {
struct element_arrows {
int width;
} arrows;
+ struct element_spikes {
+ int width;
+ int distance;
+ } spikes;
} u;
int coord_count;
struct coord *coord;
@@ -162,6 +166,7 @@ struct text *text_new(struct attr *parent, struct attr **attrs);
struct icon *icon_new(struct attr *parent, struct attr **attrs);
struct image *image_new(struct attr *parent, struct attr **attrs);
struct arrows *arrows_new(struct attr *parent, struct attr **attrs);
+struct spikes *spikes_new(struct attr *parent, struct attr **attrs);
int element_add_attr(struct element *e, struct attr *attr);
/* end of prototypes */
diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c
index aece0ea7e..73984853e 100644
--- a/navit/maptool/osm.c
+++ b/navit/maptool/osm.c
@@ -768,6 +768,7 @@ static char *attrmap= {
"w natural=wetland poly_mud\n"
"w natural=wood poly_wood\n"
"w natural=cliff cliff\n"
+ "w man_made=embankment embankment\n"
"w piste:type=downhill,piste:difficulty=advanced piste_downhill_advanced\n"
"w piste:type=downhill,piste:difficulty=easy piste_downhill_easy\n"
"w piste:type=downhill,piste:difficulty=expert piste_downhill_expert\n"
diff --git a/navit/navit.dtd b/navit/navit.dtd
index 4d6b4cfe6..2c743ada0 100644
--- a/navit/navit.dtd
+++ b/navit/navit.dtd
@@ -129,7 +129,7 @@
<!ATTLIST osd y CDATA #IMPLIED>
<!ATTLIST osd src CDATA #IMPLIED>
<!ATTLIST osd command CDATA #IMPLIED>
-<!ELEMENT itemgra (polygon|polyline|text|circle|icon|image|arrows)*>
+<!ELEMENT itemgra (polygon|polyline|text|circle|icon|image|arrows|spikes)*>
<!ATTLIST itemgra item_types CDATA #IMPLIED>
<!ATTLIST itemgra order CDATA #IMPLIED>
<!ATTLIST itemgra speed_range CDATA #IMPLIED>
@@ -165,6 +165,10 @@
<!ATTLIST arrows color CDATA #REQUIRED>
<!ATTLIST arrows width CDATA #IMPLIED>
<!ATTLIST arrows oneway CDATA #IMPLIED>
+<!ELEMENT spikes EMPTY>
+<!ATTLIST spikes color CDATA #REQUIRED>
+<!ATTLIST spikes width CDATA #IMPLIED>
+<!ATTLIST spikes distance CDATA #IMPLIED>
<!ELEMENT image EMPTY>
<!ELEMENT xi:include EMPTY>
<!ATTLIST xi:include href CDATA #IMPLIED>
diff --git a/navit/navit_layout_car_shipped.xml b/navit/navit_layout_car_shipped.xml
index 3c25259c1..a9d7a62fe 100644
--- a/navit/navit_layout_car_shipped.xml
+++ b/navit/navit_layout_car_shipped.xml
@@ -1361,9 +1361,17 @@
<itemgra item_types="rail_tram" order="10-">
<polyline color="#606060" width="2"/>
</itemgra>
- <itemgra item_types="cliff" order="12-">
+ <itemgra item_types="wall,retaining_wall" order="12-">
<polyline color="#606060" width="1"/>
</itemgra>
+ <itemgra item_types="cliff,embankment" order="12-16">
+ <polyline color="#606060" width="1"/>
+ <spikes color="#606060" width="5" distance="4"/>
+ </itemgra>
+ <itemgra item_types="cliff,embankment" order="17-">
+ <polyline color="#606060" width="1"/>
+ <spikes color="#606060" width="20" distance="10"/>
+ </itemgra>
</layer>
<layer name="labels">
<itemgra item_types="house_number" order="15-">
diff --git a/navit/xmlconfig.c b/navit/xmlconfig.c
index c47c82163..a40001de3 100644
--- a/navit/xmlconfig.c
+++ b/navit/xmlconfig.c
@@ -227,6 +227,7 @@ static int xmlconfig_announce(struct xmlstate *state) {
static struct object_func object_funcs[] = {
{ attr_announcement,NEW(announcement_new), GET(announcement_get_attr), NULL, NULL, SET(announcement_set_attr), ADD(announcement_add_attr) },
{ attr_arrows, NEW(arrows_new)},
+ { attr_spikes, NEW(spikes_new)},
{ attr_circle, NEW(circle_new), NULL, NULL, NULL, NULL, ADD(element_add_attr)},
{ attr_coord, NEW(coord_new_from_attrs)},
{ attr_cursor, NEW(cursor_new), NULL, NULL, NULL, NULL, ADD(cursor_add_attr)},
@@ -334,7 +335,7 @@ static char *element_fixmes[]= {
};
static void initStatic(void) {
- elements=g_new0(struct element_func, 45); //44 is a number of elements + ending NULL element
+ elements=g_new0(struct element_func, 46); //45 is a number of elements + ending NULL element
elements[0].name="config";
elements[0].parent=NULL;
@@ -554,6 +555,11 @@ static void initStatic(void) {
elements[43].parent="navit";
elements[43].func=NULL;
elements[43].type=attr_traffic;
+
+ elements[44].name="spikes";
+ elements[44].parent="itemgra";
+ elements[44].func=NULL;
+ elements[44].type=attr_spikes;
}
/**