summaryrefslogtreecommitdiff
path: root/navit
diff options
context:
space:
mode:
authorStefan Wildemann <gta04@metalstrolche.de>2019-07-27 11:05:40 +0200
committerStefan Wildemann <gta04@metalstrolche.de>2019-07-28 12:33:49 +0200
commitf99e5245364d2b7cf9eb1d6c9ad8a09b263f7498 (patch)
tree2a172137231cb94348ab91ba33bd6d80c75d9862 /navit
parent6bc6c0cca6c105450f7cc6f080c72d99f87c173f (diff)
downloadnavit-f99e5245364d2b7cf9eb1d6c9ad8a09b263f7498.tar.gz
Process multipolygons to mapfile
Diffstat (limited to 'navit')
-rw-r--r--navit/attr.c7
-rw-r--r--navit/attr.h134
-rw-r--r--navit/attr_def.h1
-rw-r--r--navit/item.h44
-rw-r--r--navit/layout.h130
-rw-r--r--navit/maptool/maptool.c24
-rw-r--r--navit/maptool/maptool.h171
-rw-r--r--navit/maptool/osm.c174
8 files changed, 453 insertions, 232 deletions
diff --git a/navit/attr.c b/navit/attr.c
index f7e5d1fac..0f429e533 100644
--- a/navit/attr.c
+++ b/navit/attr.c
@@ -43,6 +43,7 @@
#include "util.h"
#include "types.h"
#include "xmlconfig.h"
+#include "layout.h"
struct attr_name {
enum attr_type attr;
@@ -471,6 +472,9 @@ char *attr_to_text_ext(struct attr *attr, char *sep, enum attr_format fmt, enum
if (type == attr_nav_status) {
return nav_status_to_text(attr->u.num);
}
+ if (type == attr_poly_hole) {
+ return g_strdup_printf("osm_wayid=%lld", attr->u.poly_hole->osmid);
+ }
return g_strdup_printf("(no text[%s])", attr_to_name(type));
}
@@ -770,6 +774,9 @@ int attr_data_size(struct attr *attr) {
while (attr->u.attr_types[i++] != attr_none);
return i*sizeof(enum attr_type);
}
+ if (attr->type == attr_poly_hole) {
+ return (sizeof(attr->u.poly_hole->coord_count) + (attr->u.poly_hole->coord_count * sizeof(*attr->u.poly_hole->coord)));
+ }
dbg(lvl_error,"size for %s unknown", attr_to_name(attr->type));
return 0;
}
diff --git a/navit/attr.h b/navit/attr.h
index dca3a6107..3d691db43 100644
--- a/navit/attr.h
+++ b/navit/attr.h
@@ -35,8 +35,8 @@ enum attr_type {
#define ATTR2(x,y) attr_##y=x,
#define ATTR(x) attr_##x,
-/* Special macro for unused attribute types. Creates a placeholder entry
- * in the enum so the following values do not change. */
+ /* Special macro for unused attribute types. Creates a placeholder entry
+ * in the enum so the following values do not change. */
#define ATTR_UNUSED ATTR_UNUSED_L(__LINE__)
#define ATTR_UNUSED_L(x) ATTR_UNUSED_WITH_LINE_NUMBER(x)
#define ATTR_UNUSED_WITH_LINE_NUMBER(x) ATTR_UNUSED_##x,
@@ -52,8 +52,8 @@ enum attr_type {
};
enum attr_format {
- attr_format_default=0,
- attr_format_with_units=1,
+ attr_format_default=0,
+ attr_format_with_units=1,
};
#define AF_ONEWAY (1<<0)
@@ -120,19 +120,19 @@ enum attr_format {
/** Indicates whether a position is valid **/
enum attr_position_valid {
- attr_position_valid_invalid, /**< The position is invalid and should be discarded. **/
- attr_position_valid_static, /**< The position is valid but the vehicle is not moving, or moving very slowly.
+ attr_position_valid_invalid, /**< The position is invalid and should be discarded. **/
+ attr_position_valid_static, /**< The position is valid but the vehicle is not moving, or moving very slowly.
Calculations that involve the difference between two consecutive positions,
such as bearing, may therefore be inaccurate. **/
- attr_position_valid_extrapolated_time, /**< FIXME: this description is just my (mvglasow) guess; this value is not used anywhere as of r5957.
+ attr_position_valid_extrapolated_time, /**< FIXME: this description is just my (mvglasow) guess; this value is not used anywhere as of r5957.
The position is the vehicle's last known position, and the consumer of the
information should be aware that the vehicle may have moved since. **/
- attr_position_valid_extrapolated_spatial, /**< FIXME: this description is just my (mvglasow) guess; this value is not used anywhere as of r5957.
+ attr_position_valid_extrapolated_spatial, /**< FIXME: this description is just my (mvglasow) guess; this value is not used anywhere as of r5957.
The position is a prediction of the vehicle's current position, based on
its last known position, the time elapsed since it was obtained and possibly
other factors. This would be used for positions obtained through inertial
navigation. **/
- attr_position_valid_valid, /**< The position is valid and can be used for all purposes. **/
+ attr_position_valid_valid, /**< The position is valid and can be used for all purposes. **/
};
#define ATTR_IS_INT(x) ((x) >= attr_type_int_begin && (x) <= attr_type_int_end)
@@ -151,65 +151,66 @@ enum attr_position_valid {
#define ATTR_OBJECT(x,y) ((struct attr){attr_##x,{.navit=y}})
struct range {
- short min, max;
+ short min, max;
};
struct attr {
- enum attr_type type;
- union {
- char *str;
- void *data;
- long num;
- struct item *item;
- enum item_type item_type;
- enum projection projection;
- double * numd;
- struct color *color;
- struct coord_geo *coord_geo;
- struct navit *navit;
- struct callback *callback;
- struct callback_list *callback_list;
- struct vehicle *vehicle;
- struct layout *layout;
- struct layer *layer;
- struct map *map;
- struct mapset *mapset;
- struct log *log;
- struct route *route;
- struct navigation *navigation;
- struct coord *coord;
- struct pcoord *pcoord;
- struct gui *gui;
- struct graphics *graphics;
- struct tracking *tracking;
- struct itemgra *itemgra;
- struct plugin *plugin;
- struct plugins *plugins;
- struct polygon *polygon;
- struct polyline *polyline;
- struct circle *circle;
- struct text *text;
- struct icon *icon;
- struct image *image;
- struct arrows *arrows;
- struct element *element;
- struct speech *speech;
- struct cursor *cursor;
- struct displaylist *displaylist;
- struct transformation *transformation;
- struct vehicleprofile *vehicleprofile;
- struct roadprofile *roadprofile;
- struct bookmarks *bookmarks;
- struct config *config;
- struct osd *osd;
- struct range range;
- struct navit_object *navit_object;
- int *dash;
- enum item_type *item_types;
- enum attr_type *attr_types;
- long long *num64;
- struct attr *attrs;
- } u;
+ enum attr_type type;
+ union {
+ char *str;
+ void *data;
+ long num;
+ struct item *item;
+ enum item_type item_type;
+ enum projection projection;
+ double * numd;
+ struct color *color;
+ struct coord_geo *coord_geo;
+ struct navit *navit;
+ struct callback *callback;
+ struct callback_list *callback_list;
+ struct vehicle *vehicle;
+ struct layout *layout;
+ struct layer *layer;
+ struct map *map;
+ struct mapset *mapset;
+ struct log *log;
+ struct route *route;
+ struct navigation *navigation;
+ struct coord *coord;
+ struct pcoord *pcoord;
+ struct gui *gui;
+ struct graphics *graphics;
+ struct tracking *tracking;
+ struct itemgra *itemgra;
+ struct plugin *plugin;
+ struct plugins *plugins;
+ struct polygon *polygon;
+ struct polyline *polyline;
+ struct circle *circle;
+ struct text *text;
+ struct icon *icon;
+ struct image *image;
+ struct arrows *arrows;
+ struct element *element;
+ struct speech *speech;
+ struct cursor *cursor;
+ struct displaylist *displaylist;
+ struct transformation *transformation;
+ struct vehicleprofile *vehicleprofile;
+ struct roadprofile *roadprofile;
+ struct bookmarks *bookmarks;
+ struct config *config;
+ struct osd *osd;
+ struct range range;
+ struct navit_object *navit_object;
+ int *dash;
+ enum item_type *item_types;
+ enum attr_type *attr_types;
+ long long *num64;
+ struct attr *attrs;
+ struct poly_hole *poly_hole;
+ } u;
};
struct attr_iter;
@@ -222,7 +223,8 @@ struct attr *attr_new_from_text(const char *name, const char *value);
char *attr_to_text_ext(struct attr *attr, char *sep, enum attr_format fmt, enum attr_format def_fmt, struct map *map);
char *attr_to_text(struct attr *attr, struct map *map, int pretty);
struct attr *attr_search(struct attr **attrs, struct attr *last, enum attr_type attr);
-int attr_generic_get_attr(struct attr **attrs, struct attr **def_attrs, enum attr_type type, struct attr *attr, struct attr_iter *iter);
+int attr_generic_get_attr(struct attr **attrs, struct attr **def_attrs, enum attr_type type, struct attr *attr,
+ struct attr_iter *iter);
struct attr **attr_generic_set_attr(struct attr **attrs, struct attr *attr);
struct attr **attr_generic_add_attr(struct attr **attrs, struct attr *attr);
struct attr **attr_generic_add_attr_list(struct attr **attrs, struct attr **add);
diff --git a/navit/attr_def.h b/navit/attr_def.h
index 055936b4a..5a82d9d30 100644
--- a/navit/attr_def.h
+++ b/navit/attr_def.h
@@ -416,6 +416,7 @@ ATTR(ch_edge)
ATTR(zipfile_ref_block)
ATTR(item_id)
ATTR(pdl_gps_update)
+ATTR(poly_hole)
ATTR2(0x0004ffff,type_special_end)
ATTR2(0x00050000,type_double_begin)
ATTR(position_height)
diff --git a/navit/item.h b/navit/item.h
index 5374240d2..c3b17bdb8 100644
--- a/navit/item.h
+++ b/navit/item.h
@@ -50,7 +50,7 @@ extern int default_flags[];
#define item_type_is_area(type) ((type) >= type_area)
#define item_is_town(item) ((item).type >= type_town_label && (item).type <= type_district_label_1e7)
#define item_is_district(item) ((item).type >= type_district_label && (item).type <= type_district_label_1e7)
-#define item_is_poly_place(item) ((item).type >= type_poly_place1 && (item).type <= type_poly_place6)
+#define item_is_poly_place(item) ((item).type >= type_poly_place && (item).type <= type_poly_place6)
#define item_is_point(item) ((item).type < type_line)
#define item_is_custom_poi(item) ((item).type >= type_poi_customg && (item).type < type_line)
#define item_is_street(item) (((item).type >= type_street_nopass && (item).type <= type_roundabout) \
@@ -68,26 +68,26 @@ extern int default_flags[];
struct coord;
enum change_mode {
- change_mode_delete,
- change_mode_modify,
- change_mode_append,
- change_mode_prepend,
+ change_mode_delete,
+ change_mode_modify,
+ change_mode_append,
+ change_mode_prepend,
};
struct item_methods {
- void (*item_coord_rewind)(void *priv_data);
- int (*item_coord_get)(void *priv_data, struct coord *c, int count);
- void (*item_attr_rewind)(void *priv_data);
- int (*item_attr_get)(void *priv_data, enum attr_type attr_type, struct attr *attr);
- int (*item_coord_is_node)(void *priv_data);
- int (*item_attr_set)(void *priv_data, struct attr *attr, enum change_mode mode);
- int (*item_coord_set)(void *priv_data, struct coord *c, int count, enum change_mode mode);
- int (*item_type_set)(void *priv_data, enum item_type type);
+ void (*item_coord_rewind)(void *priv_data);
+ int (*item_coord_get)(void *priv_data, struct coord *c, int count);
+ void (*item_attr_rewind)(void *priv_data);
+ int (*item_attr_get)(void *priv_data, enum attr_type attr_type, struct attr *attr);
+ int (*item_coord_is_node)(void *priv_data);
+ int (*item_attr_set)(void *priv_data, struct attr *attr, enum change_mode mode);
+ int (*item_coord_set)(void *priv_data, struct coord *c, int count, enum change_mode mode);
+ int (*item_type_set)(void *priv_data, enum item_type type);
};
struct item_id {
- int id_hi;
- int id_lo;
+ int id_hi;
+ int id_lo;
};
#define ITEM_ID_FMT "(0x%x,0x%x)"
@@ -97,16 +97,16 @@ struct item_id {
* Represents an object on a map, such as a POI, a building, a way or a boundary.
*/
struct item {
- enum item_type type; /**< Type of the item.*/
- int id_hi; /**< First part of the ID of the item (item IDs have two parts).*/
- int id_lo; /**< Second part of the ID of the item.*/
- struct map *map; /**< The map this items belongs to.*/
- struct item_methods *meth; /**< Methods to manipulate this item.*/
- void *priv_data; /**< Private item data, only used by the map plugin which supplied this item.*/
+ enum item_type type; /**< Type of the item.*/
+ int id_hi; /**< First part of the ID of the item (item IDs have two parts).*/
+ int id_lo; /**< Second part of the ID of the item.*/
+ struct map *map; /**< The map this items belongs to.*/
+ struct item_methods *meth; /**< Methods to manipulate this item.*/
+ void *priv_data; /**< Private item data, only used by the map plugin which supplied this item.*/
};
extern struct item_range {
- enum item_type min,max;
+ enum item_type min,max;
} item_range_all;
extern struct item busy_item;
diff --git a/navit/layout.h b/navit/layout.h
index ece5d0cc8..6900f16a4 100644
--- a/navit/layout.h
+++ b/navit/layout.h
@@ -22,88 +22,94 @@
#include "item.h"
#include "color.h"
+#include "coord.h"
#ifdef __cplusplus
extern "C" {
#endif
+struct poly_hole {
+ long long osmid;
+ int coord_count;
+ struct coord coord[1];
+};
struct element {
- enum { element_point, element_polyline, element_polygon, element_circle, element_text, element_icon, element_image, element_arrows } type;
- struct color color;
- int text_size;
- union {
- struct element_point {
- char stub;
- } point;
- struct element_polyline {
- int width;
- int directed;
- int dash_num;
- int offset;
- unsigned char dash_table[4];
- } polyline;
- struct element_polygon {
- char stub;
- } polygon;
- struct element_circle {
- int width;
- int radius;
- struct color background_color;
- } circle;
- struct element_icon {
- char *src;
- int width;
- int height;
- int rotation;
- int x;
- int y;
- } icon;
- struct element_text {
- struct color background_color;
- } text;
- } u;
- int coord_count;
- struct coord *coord;
+ enum { element_point, element_polyline, element_polygon, element_circle, element_text, element_icon, element_image, element_arrows } type;
+ struct color color;
+ int text_size;
+ union {
+ struct element_point {
+ char stub;
+ } point;
+ struct element_polyline {
+ int width;
+ int directed;
+ int dash_num;
+ int offset;
+ unsigned char dash_table[4];
+ } polyline;
+ struct element_polygon {
+ char stub;
+ } polygon;
+ struct element_circle {
+ int width;
+ int radius;
+ struct color background_color;
+ } circle;
+ struct element_icon {
+ char *src;
+ int width;
+ int height;
+ int rotation;
+ int x;
+ int y;
+ } icon;
+ struct element_text {
+ struct color background_color;
+ } text;
+ } u;
+ int coord_count;
+ struct coord *coord;
};
struct itemgra {
- struct range order,sequence_range,speed_range,angle_range;
- GList *type;
- GList *elements;
+ struct range order,sequence_range,speed_range,angle_range;
+ GList *type;
+ GList *elements;
};
struct layer {
- NAVIT_OBJECT
- struct navit *navit;
- char *name;
- int details;
- GList *itemgras;
- int active;
- struct layer *ref;
+ NAVIT_OBJECT
+ struct navit *navit;
+ char *name;
+ int details;
+ GList *itemgras;
+ int active;
+ struct layer *ref;
};
struct cursor {
- struct attr **attrs;
- struct range *sequence_range;
- char *name;
- int w,h;
- int interval;
+ struct attr **attrs;
+ struct range *sequence_range;
+ char *name;
+ int w,h;
+ int interval;
};
struct layout {
- NAVIT_OBJECT
- struct navit *navit;
- char *name;
- char* dayname;
- char* nightname;
- char *font;
- struct color color;
- GList *layers;
- GList *cursors;
- int order_delta;
- int active;
+ NAVIT_OBJECT
+ struct navit *navit;
+ char *name;
+ char* dayname;
+ char* nightname;
+ char *font;
+ struct color color;
+ GList *layers;
+ GList *cursors;
+ int order_delta;
+ int active;
};
/* prototypes */
diff --git a/navit/maptool/maptool.c b/navit/maptool/maptool.c
index 422bc96bf..b785d14f4 100644
--- a/navit/maptool/maptool.c
+++ b/navit/maptool/maptool.c
@@ -555,6 +555,7 @@ static void osm_read_input_data(struct maptool_params *p, char *suffix) {
p->osm.towns=tempfile(suffix,"towns",1);
}
if (p->process_ways && p->process_nodes) {
+ p->osm.multipolygons=tempfile(suffix,"multipolygons",1);
p->osm.turn_restrictions=tempfile(suffix,"turn_restrictions",1);
p->osm.line2poi=tempfile(suffix,"line2poi",1);
p->osm.poly2poi=tempfile(suffix,"poly2poi",1);
@@ -599,6 +600,8 @@ static void osm_read_input_data(struct maptool_params *p, char *suffix) {
fclose(p->osm.nodes);
if (p->osm.turn_restrictions)
fclose(p->osm.turn_restrictions);
+ if (p->osm.multipolygons)
+ fclose(p->osm.multipolygons);
if (p->osm.associated_streets)
fclose(p->osm.associated_streets);
if (p->osm.house_number_interpolations)
@@ -723,6 +726,21 @@ static void osm_process_turn_restrictions(struct maptool_params *p, char *suffix
tempfile_unlink(suffix,"turn_restrictions");
}
+static void osm_process_multipolygons(struct maptool_params *p, char *suffix) {
+ FILE *ways_split, *ways_split_index, *relations, *coords;
+ p->osm.multipolygons=tempfile(suffix,"multipolygons",0);
+ if(!p->osm.multipolygons)
+ return;
+ relations=tempfile(suffix,"relations", 1);
+ coords=fopen("coords.tmp", "rb");
+ ways_split=tempfile(suffix,"ways_split",0);
+ ways_split_index=tempfile(suffix,"ways_split_index",0);
+ process_multipolygons(p->osm.multipolygons,coords,ways_split,ways_split_index,relations);
+ fclose(coords);
+ fclose(relations);
+ fclose(p->osm.multipolygons);
+}
+
static void maptool_dump(struct maptool_params *p, char *suffix) {
char *files[10];
int i,files_count=0;
@@ -822,6 +840,7 @@ static void maptool_assemble_map(struct maptool_params *p, char *suffix, char **
tempfile_unlink(suffix,"ways_split_ref");
tempfile_unlink(suffix,"coastline");
tempfile_unlink(suffix,"turn_restrictions");
+ tempfile_unlink(suffix,"multipolygons");
tempfile_unlink(suffix,"graph");
tempfile_unlink(suffix,"tilesdir");
tempfile_unlink(suffix,"boundaries");
@@ -1008,6 +1027,11 @@ int main(int argc, char **argv) {
if(!p.keep_tmpfiles)
tempfile_unlink(suffix,"ways_split_index");
}
+ if (start_phase(&p,"generating multipolygons")) {
+ if(p.process_relations) {
+ osm_process_multipolygons(&p, suffix);
+ }
+ }
if (p.process_relations && p.process_ways && p.process_nodes
&& start_phase(&p,"processing associated street relations")) {
struct files_relation_processing *files_relproc = files_relation_processing_new(p.osm.line2poi, suffix);
diff --git a/navit/maptool/maptool.h b/navit/maptool/maptool.h
index edb2a77ef..aef344031 100644
--- a/navit/maptool/maptool.h
+++ b/navit/maptool/maptool.h
@@ -35,37 +35,37 @@
#define RELATION_MEMBER_PARSE_FORMAT "%d:"LONGLONG_FMT":%n"
struct tile_data {
- char buffer[1024];
- int tile_depth;
- struct rect item_bbox;
- struct rect tile_bbox;
+ char buffer[1024];
+ int tile_depth;
+ struct rect item_bbox;
+ struct rect tile_bbox;
};
struct tile_parameter {
- int min;
- int max;
- int overlap;
- enum attr_type attr_to_copy;
+ int min;
+ int max;
+ int overlap;
+ enum attr_type attr_to_copy;
};
struct tile_info {
- int write;
- int maxlen;
- char *suffix;
- GList **tiles_list;
- FILE *tilesdir_out;
+ int write;
+ int maxlen;
+ char *suffix;
+ GList **tiles_list;
+ FILE *tilesdir_out;
};
extern struct tile_head {
- int num_subtiles;
- int total_size;
- char *name;
- char *zip_data;
- int total_size_used;
- int zipnum;
- int process;
- struct tile_head *next;
- // char subtiles[0];
+ int num_subtiles;
+ int total_size;
+ char *name;
+ char *zip_data;
+ int total_size_used;
+ int zipnum;
+ int process;
+ struct tile_head *next;
+ // char subtiles[0];
} *tile_head_root;
@@ -80,12 +80,12 @@ extern struct tile_head {
* @see struct attr_bin
*/
struct item_bin {
- /** Length of this item (not including this length field) in 32-bit ints. */
- int len;
- /** Item type. */
- enum item_type type;
- /** Length of the following coordinate array in 32-bit ints. */
- int clen;
+ /** Length of this item (not including this length field) in 32-bit ints. */
+ int len;
+ /** Item type. */
+ enum item_type type;
+ /** Length of the following coordinate array in 32-bit ints. */
+ int clen;
};
/**
@@ -96,27 +96,28 @@ struct item_bin {
* @see struct item_bin
*/
struct attr_bin {
- /** Length of this attribute (not including this length field) in 32-bit ints. */
- int len;
- /** Attribute type. */
- enum attr_type type;
+ /** Length of this attribute (not including this length field) in 32-bit ints. */
+ int len;
+ /** Attribute type. */
+ enum attr_type type;
};
struct item_bin_sink_func {
- int (*func)(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data);
- void *priv_data[8];
+ int (*func)(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data);
+ void *priv_data[8];
};
struct item_bin_sink {
- void *priv_data[8];
- GList *sink_funcs;
+ void *priv_data[8];
+ GList *sink_funcs;
};
#define NODE_ID_BITS 56
struct node_item {
- struct coord c;
- unsigned long long int nd_id:NODE_ID_BITS;
- char ref_way;
+ struct coord c;
+unsigned long long int nd_id:
+ NODE_ID_BITS;
+ char ref_way;
};
struct zip_info;
@@ -132,24 +133,24 @@ typedef unsigned long long int osmid;
/** Files needed for processing a relation. */
struct files_relation_processing {
- FILE *ways_in;
- FILE *ways_out;
- FILE *nodes_in;
- FILE *nodes_out;
- FILE *nodes2_in;
- FILE *nodes2_out;
+ FILE *ways_in;
+ FILE *ways_out;
+ FILE *nodes_in;
+ FILE *nodes_out;
+ FILE *nodes2_in;
+ FILE *nodes2_out;
};
/* boundaries.c */
struct boundary {
- struct item_bin *ib;
- struct country_table *country;
- char *iso2;
- GList *segments,*sorted_segments;
- GList *children;
- struct rect r;
- osmid admin_centre;
+ struct item_bin *ib;
+ struct country_table *country;
+ char *iso2;
+ GList *segments,*sorted_segments;
+ GList *children;
+ struct rect r;
+ osmid admin_centre;
};
char *osm_tag_value(struct item_bin *ib, char *key);
@@ -166,14 +167,14 @@ void free_boundaries(GList *l);
/** A buffer that can be grown as needed. */
struct buffer {
- /** Number of bytes to extend the buffer by when it must grow. */
- int malloced_step;
- /** Current allocated size (bytes). */
- long long malloced;
- /** Base address of this buffer. */
- unsigned char *base;
- /** Size of currently used part of the buffer. */
- long long size;
+ /** Number of bytes to extend the buffer by when it must grow. */
+ int malloced_step;
+ /** Current allocated size (bytes). */
+ long long malloced;
+ /** Base address of this buffer. */
+ unsigned char *base;
+ /** Size of currently used part of the buffer. */
+ long long size;
};
void save_buffer(char *filename, struct buffer *b, long long offset);
@@ -270,23 +271,24 @@ int item_order_by_type(enum item_type type);
/* osm.c */
struct maptool_osm {
- FILE *boundaries;
- FILE *turn_restrictions;
- FILE *associated_streets;
- FILE *house_number_interpolations;
- FILE *nodes;
- FILE *ways;
- FILE *line2poi;
- FILE *poly2poi;
- FILE *towns;
+ FILE *boundaries;
+ FILE *multipolygons;
+ FILE *turn_restrictions;
+ FILE *associated_streets;
+ FILE *house_number_interpolations;
+ FILE *nodes;
+ FILE *ways;
+ FILE *line2poi;
+ FILE *poly2poi;
+ FILE *towns;
};
/** Type of a relation member. */
enum relation_member_type {
- UNUSED,
- rel_member_node,
- rel_member_way,
- rel_member_relation,
+ UNUSED,
+ rel_member_node,
+ rel_member_way,
+ rel_member_relation,
};
void osm_warning(char *type, osmid id, int cont, char *fmt, ...);
@@ -305,6 +307,7 @@ void flush_nodes(int final);
void sort_countries(int keep_tmpfiles);
void process_associated_streets(FILE *in, struct files_relation_processing *files_relproc);
void process_house_number_interpolations(FILE *in, struct files_relation_processing *files_relproc);
+void process_multipolygons(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out);
void process_turn_restrictions(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out);
void process_turn_restrictions_old(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out);
void clear_node_item_buffer(void);
@@ -314,7 +317,8 @@ unsigned long long item_bin_get_nodeid(struct item_bin *ib);
unsigned long long item_bin_get_wayid(struct item_bin *ib);
unsigned long long item_bin_get_relationid(struct item_bin *ib);
void process_way2poi(FILE *in, FILE *out, int type);
-int map_resolve_coords_and_split_at_intersections(FILE *in, FILE *out, FILE *out_index, FILE *out_graph, FILE *out_coastline, int final);
+int map_resolve_coords_and_split_at_intersections(FILE *in, FILE *out, FILE *out_index, FILE *out_graph,
+ FILE *out_coastline, int final);
void write_countrydir(struct zip_info *zip_info, int max_index_size);
void osm_process_towns(FILE *in, FILE *boundaries, FILE *ways, char *suffix);
void load_countries(void);
@@ -334,8 +338,10 @@ int osm_protobufdb_load(FILE *in, char *dir);
/* osm_relations.c */
struct relations * relations_new(void);
-struct relations_func *relations_func_new(void (*func)(void *func_priv, void *relation_priv, struct item_bin *member, void *member_priv), void *func_priv);
-void relations_add_relation_member_entry(struct relations *rel, struct relations_func *func, void *relation_priv, void *member_priv, enum relation_member_type type, osmid id);
+struct relations_func *relations_func_new(void (*func)(void *func_priv, void *relation_priv, struct item_bin *member,
+ void *member_priv), void *func_priv);
+void relations_add_relation_member_entry(struct relations *rel, struct relations_func *func, void *relation_priv,
+ void *member_priv, enum relation_member_type type, osmid id);
void relations_add_relation_default_entry(struct relations *rel, struct relations_func *func);
void relations_process(struct relations *rel, FILE *nodes, FILE *ways);
void relations_destroy(struct relations *rel);
@@ -350,7 +356,8 @@ int map_collect_data_osm(FILE *in, struct maptool_osm *osm);
/* sourcesink.c */
struct item_bin_sink *item_bin_sink_new(void);
-struct item_bin_sink_func *item_bin_sink_func_new(int (*func)(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data));
+struct item_bin_sink_func *item_bin_sink_func_new(int (*func)(struct item_bin_sink_func *func, struct item_bin *ib,
+ struct tile_data *tile_data));
void item_bin_sink_func_destroy(struct item_bin_sink_func *func);
void item_bin_sink_add_func(struct item_bin_sink *sink, struct item_bin_sink_func *func);
void item_bin_sink_destroy(struct item_bin_sink *sink);
@@ -374,9 +381,9 @@ void tempfile_rename(char *suffix, char *from, char *to);
extern GHashTable *tile_hash,*tile_hash2;
struct aux_tile {
- char *name;
- char *filename;
- int size;
+ char *name;
+ char *filename;
+ int size;
};
extern GList *aux_tile_list;
@@ -415,4 +422,6 @@ void zip_close(struct zip_info *info);
void zip_destroy(struct zip_info *info);
/* Break compilation on 32 bit architectures, as we're going to cast osmid's to gpointer to use them as keys to GHashTable's */
-struct maptool_force_64 {char s[sizeof(gpointer)<sizeof(osmid)?-1:1];};
+struct maptool_force_64 {
+ char s[sizeof(gpointer)<sizeof(osmid)?-1:1];
+};
diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c
index f640c8674..00257129b 100644
--- a/navit/maptool/osm.c
+++ b/navit/maptool/osm.c
@@ -1616,8 +1616,23 @@ void osm_end_relation(struct maptool_osm *osm) {
if(attr_longest_match(attr_mapping_rel2poly_place, attr_mapping_rel2poly_place_count, &type, 1)) {
tmp_item_bin->type=type;
- } else
+ } else {
type=type_none;
+ tmp_item_bin->type=type;
+ }
+
+ fprintf(stderr,"relation_type=%s\n", relation_type);
+ if ((!g_strcmp0(relation_type, "multipolygon")) && (!boundary)) {
+ item_bin_write(tmp_item_bin, osm->multipolygons);
+ }
+
+ /*TODO: check if this was a bug: Previously attr_longest_match always failed, because
+ * item_is_poly_place never matched causing attr_mapping_rel2poly_place to be empty.
+ * Since I don't know what happenes if type suddenly is != type_none, I force the
+ * old behaviour here */
+ type=type_none;
+ tmp_item_bin->type=type;
+
if ((!g_strcmp0(relation_type, "multipolygon") || !g_strcmp0(relation_type, "boundary"))
&& (boundary || type!=type_none)) {
@@ -2643,6 +2658,163 @@ void process_house_number_interpolations(FILE *in, struct files_relation_process
g_list_free(fp.allocations);
}
+#define MEMBER_MAX 20
+struct multipolygon {
+ osmid relid;
+ struct item_bin * rel;
+ int inner_count;
+ int outer_count;
+ struct item_bin ** inner;
+ struct item_bin ** outer;
+ int order;
+};
+
+static void process_multipolygons_finish(GList *tr, FILE *out) {
+ GList *l=tr;
+ fprintf(stderr,"process_multipolygons_finish\n");
+ while(l) {
+ int a;
+ struct multipolygon *multipolygon=l->data;
+ struct rect bbox;
+ /* combine outer to full loops */
+
+ /* combine inner to full loops */
+
+ /* calculate bounding box */
+
+ /* write out */
+ int order;
+ char tilebuf[20]="";
+ struct item_bin* ib=tmp_item_bin;
+ item_bin_init(ib,multipolygon->rel->type);
+ item_bin_copy_coord(ib,multipolygon->outer[0],1);
+ item_bin_copy_attr(ib,multipolygon->rel,attr_osm_relationid);
+
+ for(a = 0; a < multipolygon->inner_count; a ++) {
+ int hole_len;
+ char * buffer;
+ int used =0;
+ osmid * id;
+ hole_len = multipolygon->inner[a]->clen *4;
+ hole_len+=4 + 8;
+ buffer=g_alloca(hole_len);
+ id = (osmid *) item_bin_get_attr(multipolygon->inner[a], attr_osm_wayid, NULL);
+ if(id !=NULL)
+ memcpy(&(buffer[used]), id, sizeof(id));
+ used += sizeof(id);
+ memcpy(&(buffer[used]), &(multipolygon->inner[a]->clen), hole_len - used);
+ item_bin_add_attr_data(ib, attr_poly_hole, buffer, hole_len);
+ }
+
+ order=tile(&bbox,"",tilebuf,sizeof(tilebuf)-1,overlap,NULL);
+ if(order > multipolygon->order)
+ order=multipolygon->order;
+
+ item_bin_add_attr_range(ib,attr_order,0,order);
+ item_bin_write(ib, out);
+
+ /* clean up this item */
+ for (a=0; a < multipolygon->inner_count; a ++)
+ g_free(multipolygon->inner[a]);
+ g_free(multipolygon->inner);
+ for (a=0; a < multipolygon->outer_count; a ++)
+ g_free(multipolygon->outer[a]);
+ g_free(multipolygon->outer);
+ g_free(multipolygon->rel);
+ g_free(multipolygon);
+ /* next item */
+ l = g_list_next(l);
+ }
+ /* done with that list. All items referred should be deleted already. */
+ g_list_free(tr);
+}
+
+static void process_multipolygons_member(void *func_priv, void *relation_priv, struct item_bin *member,
+ void *member_priv) {
+ int type=(long)member_priv;
+ int i;
+ struct multipolygon *multipolygon=relation_priv;
+ fprintf(stderr,"process_multipolygons_member id %lld, %s, outer %d, inner %d\n", multipolygon->relid,
+ (type)?"inner": "outer", multipolygon->outer_count, multipolygon->inner_count);
+ /* we remeber the whole binary item, as we may want to have the attributes later on finalize */
+ if(type) {
+ /* copy the member as inner */
+ multipolygon->inner=(struct item_bin**) g_realloc(multipolygon->inner,
+ sizeof(struct item_bin *) * (multipolygon->inner_count +1));
+ multipolygon->inner[multipolygon->inner_count]=item_bin_dup(member);
+ multipolygon->inner_count ++;
+ } else {
+ /* copy the member as outer */
+ multipolygon->outer=(struct item_bin**) g_realloc(multipolygon->outer,
+ sizeof(struct item_bin *) * (multipolygon->outer_count +1));
+ multipolygon->outer[multipolygon->outer_count]=item_bin_dup(member);
+ multipolygon->outer_count ++;
+ }
+ i=item_order_by_type(member->type);
+ if(i<multipolygon->order)
+ multipolygon->order=i;
+
+}
+
+static GList *process_multipolygons_setup(FILE *in, struct relations *relations) {
+ struct relation_member outer[MEMBER_MAX];
+ int outer_count=0;
+ struct relation_member inner[MEMBER_MAX];
+ int inner_count=0;
+ long long relid;
+ struct item_bin *ib;
+ struct relations_func *relations_func;
+ int min_count;
+ GList *multipolygons=NULL;
+
+ fseek(in, 0, SEEK_SET);
+ relations_func=relations_func_new(process_multipolygons_member, NULL);
+ while ((ib=read_item(in))) {
+ int a;
+ struct multipolygon *p_multipolygon;
+ relid=item_bin_get_relationid(ib);
+ min_count=0;
+ while((outer_count < MEMBER_MAX) && (search_relation_member(ib, "outer",&(outer[outer_count]),&min_count))) {
+ if(outer[outer_count].type != rel_member_way)
+ osm_warning("relation",relid,0,"multipolygon: wrong type for outer member ");
+ outer_count ++;
+ }
+ min_count=0;
+ while((inner_count < MEMBER_MAX) && (search_relation_member(ib, "inner",&(inner[inner_count]),&min_count))) {
+ if(inner[inner_count].type != rel_member_way)
+ osm_warning("relation",relid,0,"multipolygon: wrong type for inner member ");
+ inner_count ++;
+ }
+ fprintf(stderr,"Relid %lld: Got %d outer and %d inner\n", relid, outer_count, inner_count);
+ if(outer == 0) {
+ osm_warning("relation",relid,0,"multipolygon: missing outer member ");
+ continue;
+ }
+ p_multipolygon=g_new0(struct multipolygon, 1);
+ p_multipolygon->relid=relid;
+ p_multipolygon->order=255;
+ p_multipolygon->rel=item_bin_dup(ib);
+ for (a = 0; a < outer_count; a ++)
+ relations_add_relation_member_entry(relations, relations_func, p_multipolygon, (gpointer) 0, outer[a].type,
+ outer[a].id);
+ for (a = 0; a < inner_count; a ++)
+ relations_add_relation_member_entry(relations, relations_func, p_multipolygon, (gpointer) 1, inner[a].type,
+ inner[a].id);
+ multipolygons=g_list_append(multipolygons, p_multipolygon);
+ }
+ return multipolygons;
+}
+
+void process_multipolygons(FILE *in, FILE *coords, FILE *ways, FILE *ways_index, FILE *out) {
+ struct relations *relations=relations_new();
+ GList *multipolygons;
+ fseek(in, 0, SEEK_SET);
+ multipolygons=process_multipolygons_setup(in, relations);
+ relations_process(relations, coords, ways);
+ process_multipolygons_finish(multipolygons, out);
+ relations_destroy(relations);
+}
+
struct turn_restriction {
osmid relid;
enum item_type type;