summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wildemann <metalstrolch@users.noreply.github.com>2019-10-28 11:31:50 +0100
committerGitHub <noreply@github.com>2019-10-28 11:31:50 +0100
commitb99187ee4d8336b4c237d1be805110d41d22a14d (patch)
tree1e5de4eaac72c6042c07c35e9d1a3b0bbd6d733a
parenta0ea905c28b2e9df4984a263bdef213203c36d80 (diff)
downloadnavit-b99187ee4d8336b4c237d1be805110d41d22a14d.tar.gz
enhancement:maptool:slice big polygons into smaller parts (#906)
This commit allows to slice all polygons (except poly_water_sliced) into squares so that they fit into smaller map tiles. Holes if present are correctly sliced as well. This has the advantage that they do not need to be processed albeit not being displayed, and navit-planet-extractor can filter them out. This has the disadvantage that the big polygons are displayed checkered if the corresponding itemgra in config features an outline. TODO: Slice already on polygon creation. Currently the slicing has to be performed twice, because of tile preprocessing and saving is done in seperate steps from the tempfiles. TODO: Make the trigger for slicing configurable. Right now it slices everything smaller than tile level 4.
-rw-r--r--navit/maptool/CMakeLists.txt4
-rw-r--r--navit/maptool/boundaries.c2
-rw-r--r--navit/maptool/buffer.c2
-rw-r--r--navit/maptool/ch.c2
-rw-r--r--navit/maptool/coastline.c2
-rw-r--r--navit/maptool/itembin.c33
-rw-r--r--navit/maptool/itembin_buffer.c2
-rw-r--r--navit/maptool/itembin_slicer.c856
-rw-r--r--navit/maptool/maptool.c2
-rw-r--r--navit/maptool/maptool.h15
-rw-r--r--navit/maptool/misc.c2
-rw-r--r--navit/maptool/osm.c27
-rw-r--r--navit/maptool/osm_protobuf.c2
-rw-r--r--navit/maptool/osm_protobufdb.c2
-rw-r--r--navit/maptool/osm_psql.c2
-rw-r--r--navit/maptool/osm_relations.c2
-rw-r--r--navit/maptool/osm_xml.c2
-rw-r--r--navit/maptool/sourcesink.c2
-rw-r--r--navit/maptool/tempfile.c2
-rw-r--r--navit/maptool/tile.c13
-rw-r--r--navit/maptool/zip.c2
21 files changed, 950 insertions, 28 deletions
diff --git a/navit/maptool/CMakeLists.txt b/navit/maptool/CMakeLists.txt
index 624ea907b..8c4c824a8 100644
--- a/navit/maptool/CMakeLists.txt
+++ b/navit/maptool/CMakeLists.txt
@@ -9,8 +9,8 @@ if(BUILD_MAPTOOL)
add_executable (maptool maptool.c)
add_library (maptool_core boundaries.c buffer.c ch.c coastline.c itembin.c
- itembin_buffer.c misc.c osm.c osm_o5m.c osm_psql.c osm_relations.c
- sourcesink.c tempfile.c tile.c zip.c osm_xml.c)
+ itembin_buffer.c itembin_slicer.c misc.c osm.c osm_o5m.c osm_psql.c
+ osm_relations.c sourcesink.c tempfile.c tile.c zip.c osm_xml.c)
if(NOT MSVC)
PROTOBUF_C_GENERATE_C (PROTO_SRCS PROTO_HDRS osmformat.proto)
diff --git a/navit/maptool/boundaries.c b/navit/maptool/boundaries.c
index 2f64d092c..28322d2ee 100644
--- a/navit/maptool/boundaries.c
+++ b/navit/maptool/boundaries.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/buffer.c b/navit/maptool/buffer.c
index 08f65f2b6..a6b18e52f 100644
--- a/navit/maptool/buffer.c
+++ b/navit/maptool/buffer.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2018 Navit Team
*
diff --git a/navit/maptool/ch.c b/navit/maptool/ch.c
index 29c3f81ee..ae508a63a 100644
--- a/navit/maptool/ch.c
+++ b/navit/maptool/ch.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/coastline.c b/navit/maptool/coastline.c
index d96f86ab0..5f79db691 100644
--- a/navit/maptool/coastline.c
+++ b/navit/maptool/coastline.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/itembin.c b/navit/maptool/itembin.c
index 6f1328355..3996d6f6a 100644
--- a/navit/maptool/itembin.c
+++ b/navit/maptool/itembin.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
@@ -226,6 +226,37 @@ void item_bin_add_attr_range(struct item_bin *ib, enum attr_type type, short min
item_bin_add_attr(ib, &attr);
}
+/**
+ * @brief add a "hole" to an item
+ *
+ * This function adds a "hole" (attr_poly_hole) to a map item. It adds the
+ * coordinates and the coordinate count to the existing item.
+ * WARNING: It does NOT allocate any memory, so the memory after the item
+ * must be already allocated for that purpose.
+ * @param[inout] ib item - to add hole to
+ * @param[in] coord - hole coordinate array
+ * @param[in] ccount - number of coordinates in coord
+ */
+void item_bin_add_hole(struct item_bin * ib, struct coord * coord, int ccount) {
+ /* get space for next attr in buffer */
+ int * buffer = ((int *) ib) + ib->len +1;
+ /* get the attr heder in binary file */
+ struct attr_bin * attr = (struct attr_bin *)buffer;
+ /* fill header */
+ attr->len = (ccount *2) + 2;
+ attr->type = attr_poly_hole;
+ /* get the first attr byte in buffer */
+ buffer = (int *)(attr +1);
+ /* for poly_hole, the first 4 bytes are the coordinate count */
+ *buffer = ccount;
+ /* coordinates are behind that */
+ buffer ++;
+ /* copy in the coordinates */
+ memcpy(buffer,coord, ccount * sizeof(struct coord));
+ /* add the hole to the total size */
+ ib->len += attr->len +1;
+}
+
void item_bin_write(struct item_bin *ib, FILE *out) {
dbg_assert(fwrite(ib, (ib->len+1)*4, 1, out)==1);
}
diff --git a/navit/maptool/itembin_buffer.c b/navit/maptool/itembin_buffer.c
index 5bdf09458..590bb3162 100644
--- a/navit/maptool/itembin_buffer.c
+++ b/navit/maptool/itembin_buffer.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/itembin_slicer.c b/navit/maptool/itembin_slicer.c
new file mode 100644
index 000000000..e1a0da4ec
--- /dev/null
+++ b/navit/maptool/itembin_slicer.c
@@ -0,0 +1,856 @@
+/*
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+#include <stdlib.h>
+#include <glib.h>
+#include <assert.h>
+#include <string.h>
+#include <signal.h>
+#include <stdio.h>
+#include <math.h>
+#ifndef _MSC_VER
+#include <getopt.h>
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <zlib.h>
+#include "file.h"
+#include "item.h"
+#include "map.h"
+#include "zipfile.h"
+#include "main.h"
+#include "config.h"
+#include "linguistics.h"
+#include "plugin.h"
+
+#include "maptool.h"
+
+/**
+ * @brief advance tile number on same tile level
+ * @param[inout] buffer current tile number, after call next tile number
+ * @return void
+ */
+static void next_tile(char * buffer) {
+ int done = 0;
+ int len;
+ len = strlen(buffer);
+
+ while ((len > 0) && (!done)) {
+ if(buffer[len-1] == 'd') {
+ buffer[len-1] = 'a';
+ len --;
+ } else {
+ buffer[len-1] ++;
+ done = 1;
+ }
+ }
+}
+
+/**
+ * @brief check if rectangles overlap
+ *
+ * Ths function calculates if two rectangles overlap
+ * @param[in] b1 - one rectangle
+ * @param[in] b2 - another rectangle
+ * @return 1 if they overlap, 0 otherwise
+ */
+static int itembin_bbox_intersects (struct rect * b1, struct rect * b2) {
+ // If one rectangle is on left side of other
+ if (b1->l.x > b2->h.x || b2->l.x > b1->h.x)
+ return 0;
+
+ // If one rectangle is above other
+ if (b1->h.y < b2->l.y || b2->h.y < b1->l.y)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * @brief calculate intersection point of line with one side of an rectangle
+ *
+ * WARNING; Check if the line actually crosses the border before using this
+ * function
+ *
+ * @param[in] p1 - one point of the line
+ * @param[in] p2 - another point of the line
+ * @param[in] rect - rectangle to use as cuttinng data
+ * @param[in] edge - edge of rectangle to use. 0 left, 1 right, 2 bottom, 3 top
+ * @param[out] ret - resulting intersection point
+ */
+static void itembin_poly_intersection(struct coord *p1, struct coord *p2, struct rect *r, int edge, struct coord *ret) {
+ double dy=p2->y-p1->y;
+ double dx=p2->x-p1->x;
+ switch(edge) {
+ case 0:
+ ret->x=r->l.x;
+ ret->y=p1->y+(r->l.x-p1->x)*dy/dx;
+ break;
+ case 1:
+ ret->x=r->h.x;
+ ret->y=p1->y+(r->h.x-p1->x)*dy/dx;
+ break;
+ case 2:
+ ret->y=r->l.y;
+ ret->x=p1->x+(r->l.y-p1->y)*dx/dy;
+ break;
+ case 3:
+ ret->y=r->h.y;
+ ret->x=p1->x+(r->h.y-p1->y)*dx/dy;
+ break;
+ }
+}
+
+/**
+ * @brief calculate intersection point of line with x axis
+ *
+ * @param[in] p1 - one point of the line
+ * @param[in] p2 - another point of the line
+ * @param[in] x - x coordinate to check against
+ * @param[out y - returns y coordinate of intersection of line with x if intersecting
+ * @returns - 0 if not intersecting, 1 if y could be calculated.
+ */
+static int itembin_line_intersect_x(struct coord *p1, struct coord *p2, int x, int *y) {
+ struct rect r;
+ struct coord ret;
+ memset(&r,0,sizeof(r));
+ r.l.x = x;
+ if(((p1->x > x) && (p2->x < x)) || ((p2->x >x) && (p1->x < x))) {
+ itembin_poly_intersection(p1, p2, &r, 0, &ret);
+ *y = ret.y;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief calculate if a point is inside a polygon
+ *
+ * This function calculates if a point is inside a polygon. To do this, it casts a ray along the
+ * points x axis through the polygon and counts the intersections. If the count is even the point
+ * is outside, if odd inside
+ * @param[in] pt - point to check
+ * @param[in] poly - polygon to check
+ * @param[in] ccount - number of coordinates in poly
+ * @return 0 if outside 1 if inside
+ */
+static int itembin_poly_is_in(struct coord * pt, struct coord * poly, int ccount) {
+ int intersect_count=0;
+ /* p is first element in current buffer */
+ struct coord *p=poly;
+ /* s is lasst element in current buffer */
+ struct coord *s=poly+ ccount -1;
+ int i;
+
+ /* using x coordinate to trace. So pt is on trace */
+ for(i=0; i < ccount; i ++) {
+ if (p->x < pt->x) {
+ if(s->x > pt->x) {
+ int y=0;
+ /* we crossed the ray. calculate crossing point*/
+ if(itembin_line_intersect_x(p, s, pt->x, &y))
+ if(y < pt->y)
+ intersect_count ++;
+ }
+ } else {
+ if(s->x < pt->x) {
+ int y=0;
+ /* we crossed the ray. calculate crossing point*/
+ if(itembin_line_intersect_x(p, s, pt->x, &y))
+ if(y < pt->y)
+ intersect_count ++;
+ }
+ }
+ /* move one coordinate forward */
+ s=p;
+ p++;
+ }
+ if((intersect_count %2) ==0)
+ return 0;
+ else
+ return 1;
+
+}
+
+/**
+ * @brief data structure to eas up slicing
+ */
+struct slice_result {
+ int count; /**< number of loops / parts in coord */
+ int * ccount; /**< array of numbers of coordinates per part*/
+ struct coord ** coord; /**< array of coordinate arrays*/
+};
+
+/**
+ * @brief data structure to transfer data between this and the multipolygon
+ * code in osm.c
+ */
+struct itembin_loop_combiner_context {
+ /** combiner input */
+ int count;
+ int * ccount;
+ struct item_bin ** part;
+ /** combiner result */
+ int sequence_count;
+ int *scount;
+ int *direction;
+ int **sequences;
+};
+
+/**
+ * @brief data structure to make partd of an item easily avalable for the slicer code
+ */
+struct slicerpolygon {
+ struct item_bin * ib; /**< reference to the original item */
+ /* transfer through the layers */
+ FILE* reference;
+ char * buffer;
+ struct tile_info *info;
+ int number;
+ /* decoded data */
+ struct rect bbox; /**< bbox of the polygons outline */
+ int count; /**< number of coordinates in outer polygon */
+ struct coord * poly; /**< outer polygon */
+ int hole_count; /**< number of hole polygons */
+ int * ccount; /**< number of coordinates per hole polygon */
+ struct coord ** holes; /**< the hole polygons */
+ struct rect * holes_bbox; /**< bboxes of the hole polygons */
+ int attr_len; /**< length of attrs in bytes including the holes as is */
+ struct attr_bin * attrs; /**< first byte of the attrs */
+ int f_attr_len; /**< number of bytes attrs without the holes */
+ struct attr_bin * f_attrs; /**< first byte of attr imege with holes removed */
+};
+
+/**
+ * @brief free all possibly allocated members of a itembin_loop_combiner_context
+ *
+ * @param c - context to clear
+ */
+static void clear_loop_combiner_context(struct itembin_loop_combiner_context * c) {
+ int i;
+ for(i=0; i < c->count; i ++) {
+ if(c->part[i] != NULL)
+ g_free(c->part[i]);
+ }
+ if(c->ccount != NULL)
+ g_free(c->ccount);
+
+ if(c->part != NULL)
+ g_free(c->part);
+
+ for(i=0; i < c->sequence_count; i ++) {
+ if(c->sequences[i] != NULL)
+ g_free(c->sequences[i]);
+ }
+ if(c->scount != NULL)
+ g_free(c->scount);
+
+ if(c->direction != NULL)
+ g_free(c->direction);
+
+ if(c->sequences != NULL)
+ g_free(c->sequences);
+}
+
+/**
+ * @brief free all possibly allocated members of a slice_result
+ *
+ * @param r - context to clear
+ */
+static void clear_slice_result (struct slice_result * r) {
+ int i;
+ for(i=0; i < r->count; i ++) {
+ if(r->coord[i] != NULL)
+ g_free(r->coord[i]);
+ }
+ if(r->ccount !=NULL)
+ g_free(r->ccount);
+ if(r->coord !=NULL)
+ g_free(r->coord);
+
+ memset(r, 0, sizeof(*r));
+}
+
+/**
+ * @brief add a part to a slice result structure
+ *
+ * This function adds a given line part to a slice result. It allocates the
+ * required space for pointers, but keeps the memory of the parts coordinate array.
+ * the coordinate should not be freed outside
+ *
+ * @param[in] r - slice result structure
+ * @param[in] part - new part coordinate array to add
+ * @param[in] ccount - number of coordinates in new part array.
+ */
+static void itembin_slice_add_part(struct slice_result *r, struct coord * part, int ccount) {
+ r->ccount = g_realloc(r->ccount, sizeof(int) * (r->count +1));
+ r->ccount[r->count] = ccount;
+ r->coord = g_realloc(r->coord, sizeof(struct coord *) * (r->count +1));
+ r->coord[r->count] = part;
+ r->count ++;
+}
+
+#if 0
+static void dump_coords(struct coord *coords, int ccount, FILE* file) {
+ int i;
+ for (i=0; i < ccount; i ++) {
+ fprintf(file, "(%d,%d)",coords[i].x, coords[i].y);
+ }
+ fprintf(file, "\n");
+}
+#endif
+
+/**
+ * @brief combine the parts of a slice result to closed loops
+ *
+ * This function uses the osm.c multipolygon code to combine the given parts
+ * of a slice resutl structure to closed loops,
+ *
+ * @param[inout] r - slice result to reassign to loops.
+ */
+static void itembin_loop_combiner (struct slice_result *r) {
+ struct slice_result out;
+ struct itembin_loop_combiner_context c;
+ memset(&out, 0, sizeof(out));
+ /* prepare context for reusing multipolygon processing parts */
+ memset(&c, 0, sizeof(c));
+ int i;
+ c.count = r->count;
+ c.ccount = g_malloc(r->count * sizeof(int));
+ c.part = g_malloc(r->count * sizeof(struct item_bin *));
+ for(i=0; i < c.count; i ++) {
+ c.ccount[i] = r->ccount[i];
+ c.part[i] = (struct item_bin *) g_malloc(r->ccount[i] * sizeof(struct coord) + sizeof(struct item_bin));
+ c.part[i]->type = 0;
+ c.part[i]->clen = r->ccount[i] * 2;
+ memcpy(c.part[i] +1, r->coord[i], r->ccount[i] * sizeof(struct coord));
+ c.part[i]->len = (sizeof(struct item_bin) /4) -1 + c.part[i]->clen;
+ }
+ /* call multipolygon processing part */
+ c.sequence_count = process_multipolygons_find_loops(0, c.count, c.part, &(c.scount), &(c.sequences), &(c.direction));
+ /* assemble new slice_result */
+ for(i = 0; i < c.sequence_count; i ++) {
+ int ccount = 0;
+ struct coord * loop = NULL;
+ /* count total coordinates for new loop */
+ ccount = process_multipolygons_loop_count(c.part, c.scount[i], c.sequences[i]);
+ /* alloc memory for new loop */
+ loop = (struct coord *) g_malloc0(ccount * sizeof(struct coord));
+ /* copy in coordinates */
+ ccount = process_multipolygons_loop_dump(c.part, c.scount[i], c.sequences[i], c.direction, loop);
+ /* attach to result */
+ itembin_slice_add_part(&out, loop, ccount);
+ /* do not free loop. */
+ }
+
+ //fprintf(stderr, "Combined to %d loops %d parts\n", c.sequence_count, out.count);
+ clear_loop_combiner_context(&c);
+ /* copy back the result */
+ clear_slice_result(r);
+ *r = out;
+
+}
+
+/**
+ * @brief sort functions for qsort to sort coordinates along x or y axis
+ * @param[in] a - coordinate a
+ * @param[in] b - coordinate b
+ * @param[in] axis - 1 if x axis, 0 if y axis
+ * @return <1 a<b 0 a==b >1 a>b
+ */
+static inline int itembin_sort_coordinates_xy(const void * a, const void * b, int axis) {
+ struct coord * c1 = (struct coord *) a;
+ struct coord * c2 = (struct coord *) b;
+ if(axis) {
+ return (c1->x - c2->x);
+ } else {
+ return (c1->y - c2->y);
+ }
+}
+
+/**
+ * @brief sort functions for qsort to sort coordinates along x axis
+ * @param[in] a - coordinate a
+ * @param[in] b - coordinate b
+ * @return <1 a<b 0 a==b >1 a>b
+ */
+static int itembin_sort_coordinates_x(const void * a, const void * b) {
+ return itembin_sort_coordinates_xy(a,b,1);
+}
+
+/**
+ * @brief sort functions for qsort to sort coordinates along y axis
+ * @param[in] a - coordinate a
+ * @param[in] b - coordinate b
+ * @return <1 a<b 0 a==b >1 a>b
+ */
+static int itembin_sort_coordinates_y(const void * a, const void * b) {
+ return itembin_sort_coordinates_xy(a,b,0);
+}
+
+/**
+ * @brief srt coordinates along cut edge
+ *
+ * @param[inout] coord - array of points on one axis. Sorted on return.
+ * @param[in] ccpunt - number of coords in coord
+ * @param[in] edge - 0 or 1, sort along y axis, 2 or 3 sort along x axis
+ */
+static void itembin_sort_coordinates(struct coord * coord, int ccount, int edge) {
+ if((edge==0) || (edge==1))
+ qsort(coord, ccount,sizeof(struct coord),itembin_sort_coordinates_y);
+ else
+ qsort(coord, ccount,sizeof(struct coord),itembin_sort_coordinates_x);
+}
+
+static void itembin_slice_part_direction(struct coord *p_in, int p_in_ccount, struct slice_result * p_out, int edge,
+ struct rect * box, struct coord ** cutpoints, int* cutpoint_ccount) {
+ int i;
+
+ /* get some space */
+ int part_ccount =0;
+ struct coord * part = g_malloc((p_in_ccount + 4) * sizeof(struct coord));
+ *cutpoint_ccount =0;
+ /* hold the cut points */
+ *cutpoints=g_malloc((p_in_ccount * 8 + 4) * sizeof(struct coord));
+
+ /* p is first element in current buffer */
+ struct coord *p=p_in;
+ /* s is lasst element in current buffer */
+ struct coord *s=p_in+ p_in_ccount -1;
+
+ /* iterate all point in this loop, remember the cut points, remember the parts */
+ for(i=0; i < p_in_ccount; i ++) {
+ if (geom_is_inside(p, box, edge)) {
+ if (! geom_is_inside(s, box, edge)) {
+ struct coord pi;
+ /* current segment crosses border from outside to inside. Add crossing point with border first */
+ itembin_poly_intersection(s,p,box,edge,&pi);
+ part[part_ccount++]=pi;
+ /* remember the cutpoint */
+ (*cutpoints)[(*cutpoint_ccount)++]=pi;
+ }
+ /* add point if inside */
+ part[part_ccount++]=*p;
+ } else {
+ if (geom_is_inside(s, box, edge)) {
+ struct coord pi;
+ /*current segment crosses border from inside to outside. Add crossing point with border */
+ itembin_poly_intersection(p,s,box,edge,&pi);
+ part[part_ccount++]=pi;
+ /* remember the cutpoint */
+ (*cutpoints)[(*cutpoint_ccount)++]=pi;
+ /*this part is complete. add it to result */
+ itembin_slice_add_part(p_out, part, part_ccount);
+ /* do NOT free this part as it has been added */
+ /* new buffer, new part */
+ part = g_malloc((p_in_ccount +4) * sizeof(struct coord));
+ part_ccount = 0;
+ }
+ /* skip point if outside */
+ }
+ /* move one coordinate forward */
+ s=p;
+ p++;
+ }
+ if(part_ccount > 0) {
+ /* some points left. We started not at the border */
+ if (geom_is_inside(p_in, box, edge))
+ part[part_ccount++]=*(p_in);
+ itembin_slice_add_part(p_out, part, part_ccount);
+ /* do NOT free this part as it has been added */
+ } else {
+ /* we allocated a new buffer for the next part, but there were no points left. */
+ g_free(part);
+ }
+}
+
+static void itembin_slice_direction(struct slice_result * p_in_outer, struct slice_result *p_in_inner,
+ struct slice_result * p_out_outer, struct slice_result * p_out_inner, int edge, struct rect * box) {
+ int outer;
+ int inner;
+ int outer_cutpoint_ccount=0;
+ struct coord * outer_cutpoints = NULL;
+ //fprintf(stderr,"going to slice %d loops %d holes\n", p_in_outer->count, p_in_inner->count);
+ for(outer=0; outer < p_in_outer->count; outer ++) {
+ int i;
+ /* get some space */
+ int cutpoint_ccount =0;
+ /* hold the cut points */
+ struct coord * cutpoints=NULL;;
+
+ /* cut this loop into pieces */
+ itembin_slice_part_direction(p_in_outer->coord[outer], p_in_outer->ccount[outer], p_out_outer, edge,
+ box, &cutpoints, &cutpoint_ccount);
+ if(cutpoint_ccount > 0) {
+ outer_cutpoints=g_realloc(outer_cutpoints, (outer_cutpoint_ccount + cutpoint_ccount) * sizeof(struct coord));
+ for(i=0; i < cutpoint_ccount; i ++) {
+ outer_cutpoints[outer_cutpoint_ccount + i] = cutpoints[i];
+ }
+ outer_cutpoint_ccount += cutpoint_ccount;
+ }
+ /* clear the cutpoints if we got any */
+ if(cutpoints != NULL)
+ g_free(cutpoints);
+
+ }
+ for(inner=0; inner < p_in_inner->count; inner ++) {
+ int i;
+ /* get some space */
+ int cutpoint_ccount =0;
+ /* hold the cut points */
+ struct coord * cutpoints =NULL;
+ struct slice_result temp;
+ memset(&temp, 0, sizeof(temp));
+
+ /* cut this loop into pieces */
+ itembin_slice_part_direction(p_in_inner->coord[inner], p_in_inner->ccount[inner], &temp, edge,
+ box, &cutpoints, &cutpoint_ccount);
+
+ /* if we have cutlines, we need to add the remains of this loop to outer loop */
+ if(cutpoint_ccount > 0) {
+ int a;
+ outer_cutpoints=g_realloc(outer_cutpoints, (outer_cutpoint_ccount + cutpoint_ccount) * sizeof(struct coord));
+ for(i=0; i < cutpoint_ccount; i ++) {
+ outer_cutpoints[outer_cutpoint_ccount + i] = cutpoints[i];
+ }
+ outer_cutpoint_ccount += cutpoint_ccount;
+ /* move the parts to the outer loop */
+ for(a = 0; a < temp.count; a ++) {
+ itembin_slice_add_part(p_out_outer, temp.coord[a], temp.ccount[a]);
+ /* unlink from tem not to get freed later by clear_slice_result */
+ temp.coord[a] = NULL;
+ }
+ } else {
+ int a;
+ /* move the parts to the inner loop */
+ for(a = 0; a < temp.count; a ++) {
+ itembin_slice_add_part(p_out_inner, temp.coord[a], temp.ccount[a]);
+ /* unlink from tem not to get freed later by clear_slice_result */
+ temp.coord[a] = NULL;
+ }
+ }
+ /* clear temp */
+ clear_slice_result(&temp);
+ /* clear the cutpoints if we got any */
+ if(cutpoints != NULL)
+ g_free(cutpoints);
+ }
+
+ /* calculate and add the outer cut lines (there are no inner) */
+ if(outer_cutpoint_ccount >0) {
+ int i;
+ struct coord * part;
+ /* sort the cut points */
+ //dump_coords(outer_cutpoints, outer_cutpoint_ccount, stderr);
+ itembin_sort_coordinates(outer_cutpoints, outer_cutpoint_ccount, edge);
+ //dump_coords(outer_cutpoints, outer_cutpoint_ccount, stderr);
+ /* add the cut lines */
+ for (i = 0; i < outer_cutpoint_ccount; i+=2) {
+ part = g_malloc(sizeof(struct coord) * 4);
+ part[0] = outer_cutpoints[i];
+ part[1] = outer_cutpoints[i];
+ part[2] = outer_cutpoints[i+1];
+ part[3] = outer_cutpoints[i+1];
+ itembin_slice_add_part(p_out_outer, part, 4);
+ /* do NOT free this part as it has been added */
+ }
+ }
+
+ if(outer_cutpoints != NULL)
+ g_free(outer_cutpoints);
+ /* reassemble the parts to loops */
+ //fprintf(stderr, "reassemble %d outer parts\n", p_out_outer->count);
+ itembin_loop_combiner (p_out_outer);
+ //fprintf(stderr, "reassemble %d inner parts\n", p_out_inner->count);
+ itembin_loop_combiner (p_out_inner);
+ //fprintf(stderr, "slicing resulted in %d parts outer, %d parts inner\n", p_out_outer->count, p_out_inner->count);
+}
+
+
+static void itembin_write_slice_result (struct slicerpolygon * sp, struct slice_result * outer,
+ struct slice_result * inner) {
+ int i;
+ int hole_size = 0;
+ /* calculate maximum space for loops */
+ for(i=0; i < inner->count; i ++) {
+ /* add space for the coordnates */
+ hole_size += inner->ccount[i] * sizeof(struct coord);
+ /* add space for attr overhead */
+ hole_size += sizeof(int) * 8;
+ }
+ for(i=0; i < outer->count; i ++) {
+ int h;
+ struct item_bin * out;
+ char buffer[50];
+ snprintf(buffer, 50, "slice %d", sp->number);
+ out = g_malloc(sizeof(struct item_bin) + (outer->ccount[i] * sizeof(struct coord)) + sp->f_attr_len + 50 + hole_size);
+ out->type = sp->ib->type;
+ out->clen = outer->ccount[i] * 2;
+ memcpy(out +1, outer->coord[i], outer->ccount[i] * sizeof(struct coord));
+ memcpy((struct coord *)(out +1) + outer->ccount[i], sp->f_attrs, sp->f_attr_len);
+ out->len = ((sizeof(struct item_bin) + sp->f_attr_len) / 4) -1 + out->clen;
+ item_bin_add_attr_string(out, attr_debug, buffer);
+ /* add holes */
+ for(h=0; h < inner->count; h ++) {
+ if(itembin_poly_is_in(inner->coord[h], outer->coord[i], outer->ccount[i]))
+ item_bin_add_hole(out, inner->coord[h], inner->ccount[h]);
+ }
+ tile_write_item_to_tile(sp->info, out, sp->reference, sp->buffer);
+ g_free(out);
+ }
+}
+
+static void itembin_slice(struct slicerpolygon * sp, struct rect *box) {
+ int i;
+ struct slice_result inner;
+ struct slice_result outer;
+ struct slice_result out_inner;
+ struct slice_result out_outer;
+ struct slice_result * p_in_inner = &inner;
+ struct slice_result * p_out_inner = &out_inner;
+ struct slice_result * p_in_outer = &outer;
+ struct slice_result * p_out_outer = &out_outer;
+ memset(&outer, 0, sizeof(outer));
+ memset(&inner, 0, sizeof(inner));
+ memset(&out_outer, 0, sizeof(out_outer));
+ memset(&out_inner, 0, sizeof(out_inner));
+
+ /*prepare in for first round */
+ /* outer */
+ outer.count=1;
+ outer.ccount=g_malloc(sizeof(int) * outer.count);
+ outer.coord=g_malloc(sizeof(struct coord*) * outer.count);
+ outer.coord[0]=g_malloc(sizeof(struct coord) * sp->count);
+ memcpy(outer.coord[0], sp->poly, sizeof(struct coord) * sp->count);
+ outer.ccount[0] = sp->count;
+ /* holes or inner if matching box*/
+ inner.count=0;
+ inner.ccount=g_malloc(sizeof(int) * sp->hole_count);
+ inner.coord=g_malloc(sizeof(struct coord*) * sp->hole_count);
+ for(i=0; i < sp->hole_count; i ++) {
+ if(itembin_bbox_intersects (&sp->holes_bbox[i], box)) {
+ //fprintf(stderr, "Got intersecting hole %d %d coords\n",i,sp->ccount[i]);
+ inner.coord[inner.count]=g_malloc(sizeof(struct coord) * sp->ccount[i]);
+ memcpy(inner.coord[inner.count], sp->holes[i], sizeof(struct coord) * sp->ccount[i]);
+ inner.ccount[inner.count] = sp->ccount[i];
+ inner.count ++;
+ }
+ }
+ //fprintf(stderr,"%d holes intersecting this tile\n", inner.count);
+
+ /* cut for all 4 directions */
+ for(i =0; i < 4; i ++) {
+ itembin_slice_direction(p_in_outer,p_in_inner, p_out_outer, p_out_inner, i, box);
+ /* clear old input */
+ clear_slice_result(p_in_outer);
+ clear_slice_result(p_in_inner);
+ /* switch buffer */
+ if(p_in_outer == &outer) {
+ p_out_outer = &outer;
+ p_in_outer = &out_outer;
+ p_out_inner = &inner;
+ p_in_inner = &out_inner;
+ } else {
+ p_out_outer = &out_outer;
+ p_in_outer = &outer;
+ p_out_inner = &out_inner;
+ p_in_inner = &inner;
+ }
+ }
+
+ /* write the result to tiles */
+ itembin_write_slice_result (sp, &outer, &inner);
+
+ /* clean up */
+ clear_slice_result(&inner);
+ clear_slice_result(&outer);
+
+}
+
+
+/**
+ * @brief copy item_bin attrs filtering out one kind
+ *
+ * @param[in] in - attrs to filter
+ * @param[in] size - attrs total size in bytes
+ * @param[out] out - space for filtered attr. At least size long.
+ * @param[in] remove - type of item to remove from attr
+ */
+static int itembin_filter_attr(struct attr_bin * in, int size, struct attr_bin * out, enum attr_type remove) {
+ int nout=0;
+ char * in_pos = (char *) in;
+ char * out_pos = (char *) out;
+ while(in_pos < ((char*)in) + size ) {
+ struct attr_bin * reader=(struct attr_bin *) in_pos;
+ if(reader-> type != remove) {
+ /* write it */
+ struct attr_bin * writer = (struct attr_bin *) out_pos;
+ memcpy(writer, reader, (reader->len+1) *4);
+ /* calculate new writer position */
+ nout +=(reader->len+1) *4;
+ out_pos +=(reader->len+1) *4;
+ }
+ /* calculate new posotion */
+ in_pos +=(reader->len+1) *4;
+ }
+ return nout;
+}
+
+/**
+ * @brief free structure filled by itembin_disassemble
+ * @param sp structure to free
+ */
+static void itembin_slicerpolygon_free(struct slicerpolygon * sp) {
+ if(sp->ccount != NULL)
+ g_free(sp->ccount);
+ if(sp->holes != NULL)
+ g_free(sp->holes);
+ if(sp->holes_bbox != NULL)
+ g_free(sp->holes_bbox);
+ if(sp->f_attrs != NULL)
+ g_free(sp->f_attrs);
+}
+
+/**
+ * @brief parse an item_bin and make it's contents accessable.
+ *
+ * This method parses the contents of a item_bin and makes it accessable via direct
+ * pointers. Additionally it filters out holes if any from attr. This allows easy
+ * reassembly of the sliced parts to item_bins.
+ * @param[in] ib item to disassemble
+ * @param{out] out structure containing the parsing result.
+ */
+static void itembin_disassemble (struct item_bin *ib, struct slicerpolygon * out) {
+ struct attr_bin *ab=NULL;
+ /* basic setup*/
+ out->ib = ib;
+ out->count = ib->clen / 2;
+ out->poly = (struct coord *)(ib +1);
+ bbox(out->poly, out->count, &out->bbox);
+ /* init hole storage */
+ out->hole_count=0;
+ out->ccount = NULL;
+ out->holes = NULL;
+ out->holes_bbox = NULL;
+ /* scan for holes and extract pointers to coordinates */
+ while ((ab=item_bin_get_attr_bin(ib, attr_poly_hole, ab))!=NULL) {
+ /* got one hole */
+ /* realloc ccount and holes and holes_bbox*/
+ out->ccount = g_realloc(out->ccount, sizeof(int) * (out->hole_count +1));
+ out->holes = g_realloc(out->holes, sizeof(struct coord *) * (out->hole_count +1));
+ out->holes_bbox = g_realloc(out->holes_bbox, sizeof(struct rect) * (out->hole_count +1));
+ /* get ccount */
+ out->ccount[out->hole_count] = *(int*)(ab + 1);
+ /* get hole coords */
+ out->holes[out->hole_count] = (struct coord *)((int *)(ab + 1) + 1);
+ /* get hole bbox */
+ bbox(out->holes[out->hole_count], out->ccount[out->hole_count], &(out->holes_bbox[out->hole_count]));
+ /* count hole */
+ out->hole_count ++;
+ /* next attr */
+ ab ++;
+ }
+ /* get attr pointer and size */
+ out->attrs = (struct attr_bin *) (out->poly + out->count);
+ out->attr_len = (ib->len - ib->clen +1) * 4 - sizeof(struct item_bin);
+
+ /* get memory for filtered attrs */
+ out->f_attrs=g_malloc(out->attr_len);
+ /* filter_attrs */
+ out->f_attr_len=itembin_filter_attr(out->attrs, out->attr_len, out->f_attrs, attr_poly_hole);
+
+ //fprintf(stderr,"Got %d coords and %d holes. %d bytes attrs, %d without holes\n", out->count, out->hole_count,
+ // out->attr_len, out->f_attr_len);
+}
+
+void itembin_nicer_slicer(struct tile_info *info, struct item_bin *ib, FILE *reference, char * buffer, int min) {
+ char tilecode[22];
+ char tileend[22];
+ struct slicerpolygon sp;
+ long long * id;
+ int is_relation=0;
+
+ /* for now only slice polygons and things > min. */
+ if (ib->type < type_area || min <= tile_len(buffer)) {
+ tile_write_item_to_tile(info, ib, reference, buffer);
+ return;
+ }
+
+ id = item_bin_get_attr(ib, attr_osm_wayid, NULL);
+ if(id!= NULL) {
+ is_relation = 0;
+ } else {
+ id = item_bin_get_attr(ib, attr_osm_relationid, NULL);
+ is_relation =1;
+ }
+
+ /* seems we have a polygon. Calculate tile range from*/
+ memset(tilecode, 0, sizeof(tilecode));
+ memset(tilecode,'a', min);
+ memcpy(tilecode, buffer, tile_len(buffer));
+ /* to */
+ memset(tileend, 0, sizeof(tileend));
+ memset(tileend,'d', min);
+ memcpy(tileend, buffer, tile_len(buffer));
+ next_tile(tileend);
+
+ if(id != NULL) {
+ if(is_relation)
+ osm_info("relation",*id,0,"slice down %d steps from %s to (%s - %s)\n",min - tile_len(buffer), buffer, tilecode,
+ tileend);
+ else
+ osm_info("way",*id,0,"slice down %d steps from %s to (%s - %s)\n",min - tile_len(buffer), buffer, tilecode, tileend);
+
+ }
+ itembin_disassemble (ib, &sp);
+ sp.reference = reference;
+ sp.info = info;
+ sp.buffer = buffer;
+ sp.number=0;
+
+ /* for all tiles in range. Allow this to overflow if tile_len(buffer) == 0*/
+ do {
+ struct rect bbox;
+ /* get tile rectangle. One might like slicing without overlap, but since the
+ * overlapping tiles do not cover the same area per tile code than the
+ * overlapping ones we cannot. This will look ugly. But there is no chance.*/
+ tile_bbox(tilecode, &bbox, overlap);
+
+ /* only process tiles which do intersect wit ib's bbox */
+ if(!itembin_bbox_intersects (&sp.bbox, &bbox)) {
+ next_tile(tilecode);
+ sp.number ++;
+ continue;
+ }
+ fprintf(stderr, "slice %d intersection with %s\n", sp.number, tilecode);
+ sp.buffer=tilecode;
+ itembin_slice(&sp, &bbox);
+
+ /* next tile */
+ next_tile(tilecode);
+ sp.number ++;
+ } while (strcmp(tilecode,tileend) != 0);
+ itembin_slicerpolygon_free(&sp);
+}
+
diff --git a/navit/maptool/maptool.c b/navit/maptool/maptool.c
index 5b2b7d32c..54a68135c 100644
--- a/navit/maptool/maptool.c
+++ b/navit/maptool/maptool.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/maptool.h b/navit/maptool/maptool.h
index 5a97c8186..37590e30b 100644
--- a/navit/maptool/maptool.h
+++ b/navit/maptool/maptool.h
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
@@ -211,6 +211,7 @@ struct attr_bin * item_bin_get_attr_bin(struct item_bin *ib, enum attr_type type
struct attr_bin * item_bin_get_attr_bin_last(struct item_bin *ib);
void item_bin_add_attr_longlong(struct item_bin *ib, enum attr_type type, long long val);
void item_bin_add_attr_string(struct item_bin *ib, enum attr_type type, char *str);
+void item_bin_add_hole(struct item_bin * ib, struct coord * coord, int ccount);
void item_bin_add_attr_range(struct item_bin *ib, enum attr_type type, short min, short max);
void item_bin_remove_attr(struct item_bin *ib, void *ptr);
void item_bin_write(struct item_bin *ib, FILE *out);
@@ -232,6 +233,10 @@ struct item_bin *read_item_range(FILE *in, int *min, int *max);
struct item_bin *init_item(enum item_type type);
extern struct item_bin *tmp_item_bin;
+/* itembin_slicer.c */
+void itembin_nicer_slicer(struct tile_info *info, struct item_bin *ib, FILE *reference, char * buffer, int min);
+
+
/* maptool.c */
extern long long slice_size;
@@ -423,6 +428,14 @@ void zip_set_zipnum(struct zip_info *info, int num);
void zip_close(struct zip_info *info);
void zip_destroy(struct zip_info *info);
+/* osm.c */
+int process_multipolygons_find_loops(osmid relid, int in_count, struct item_bin ** parts, int **scount,
+ int *** sequences,
+ int **direction);
+int process_multipolygons_loop_dump(struct item_bin** bin, int scount, int*sequence, int*direction,
+ struct coord * buffer);
+int process_multipolygons_loop_count(struct item_bin** bin, int scount, int*sequence);
+
/* 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];
diff --git a/navit/maptool/misc.c b/navit/maptool/misc.c
index 9b1c72da2..2b71ccde0 100644
--- a/navit/maptool/misc.c
+++ b/navit/maptool/misc.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2008 Navit Team
*
diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c
index 97ae5d1cf..c6308c2b4 100644
--- a/navit/maptool/osm.c
+++ b/navit/maptool/osm.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
@@ -2805,9 +2805,9 @@ static int process_multipolygons_find_loop(int in_count, struct item_bin ** part
return 0;
}
-static int process_multipolygons_find_loops(osmid relid, int in_count, struct item_bin ** parts, int **scount,
- int *** sequences,
- int **direction) {
+int process_multipolygons_find_loops(osmid relid, int in_count, struct item_bin ** parts, int **scount,
+ int *** sequences,
+ int **direction) {
int done=0;
int loop_count=0;
int *used;
@@ -2846,8 +2846,8 @@ static int process_multipolygons_find_loops(osmid relid, int in_count, struct it
return loop_count;
}
-static int process_multipolygons_loop_dump(struct item_bin** bin, int scount, int*sequence, int*direction,
- struct coord * buffer) {
+int process_multipolygons_loop_dump(struct item_bin** bin, int scount, int*sequence, int*direction,
+ struct coord * buffer) {
int points = 0;
int a;
@@ -2891,7 +2891,7 @@ static int process_multipolygons_loop_dump(struct item_bin** bin, int scount, in
* @param sequence sequence calculated by process_multipolygon_find_loop
* @returns number of coords
*/
-static int process_multipolygons_loop_count(struct item_bin** bin, int scount, int*sequence) {
+int process_multipolygons_loop_count(struct item_bin** bin, int scount, int*sequence) {
return process_multipolygons_loop_dump(bin,scount,sequence,NULL,NULL);
}
@@ -3083,6 +3083,19 @@ static void process_multipolygons_setup_one(struct item_bin * ib, struct relatio
/*realloc outer to make space for next */
outer = g_realloc(outer, sizeof(struct relation_member) * (outer_count +1));
}
+ /* in ancient times of OSM, multipolygons were created having no "role" for outer loop members.
+ * There are still such multipolygons. Rescue most of them, by treating the role less members
+ * as outer. These multiolygons are treated a mistake nowadays, but even now some editing tools
+ * seem to create such.*/
+ min_count=0;
+ while(search_relation_member(ib, "",&(outer[outer_count]),&min_count)) {
+ //osm_warning("relation",relid,0,"multipolygon: using empty role type as outer\n");
+ if(outer[outer_count].type != rel_member_way)
+ osm_warning("relation",relid,0,"multipolygon: wrong type for outer member\n");
+ outer_count ++;
+ /*realloc outer to make space for next */
+ outer = g_realloc(outer, sizeof(struct relation_member) * (outer_count +1));
+ }
min_count=0;
while(search_relation_member(ib, "inner",&(inner[inner_count]),&min_count)) {
if(inner[inner_count].type != rel_member_way)
diff --git a/navit/maptool/osm_protobuf.c b/navit/maptool/osm_protobuf.c
index 4f71010e4..e38a111f6 100644
--- a/navit/maptool/osm_protobuf.c
+++ b/navit/maptool/osm_protobuf.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/osm_protobufdb.c b/navit/maptool/osm_protobufdb.c
index 64b601280..a2343c707 100644
--- a/navit/maptool/osm_protobufdb.c
+++ b/navit/maptool/osm_protobufdb.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/osm_psql.c b/navit/maptool/osm_psql.c
index a8dac6914..c4a936723 100644
--- a/navit/maptool/osm_psql.c
+++ b/navit/maptool/osm_psql.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/osm_relations.c b/navit/maptool/osm_relations.c
index 3d05caab7..bb7a48811 100644
--- a/navit/maptool/osm_relations.c
+++ b/navit/maptool/osm_relations.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/osm_xml.c b/navit/maptool/osm_xml.c
index 6cef06493..9fe3ac093 100644
--- a/navit/maptool/osm_xml.c
+++ b/navit/maptool/osm_xml.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/sourcesink.c b/navit/maptool/sourcesink.c
index eedd433d9..d240c67f5 100644
--- a/navit/maptool/sourcesink.c
+++ b/navit/maptool/sourcesink.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/tempfile.c b/navit/maptool/tempfile.c
index bdb4dad96..3a4895b9e 100644
--- a/navit/maptool/tempfile.c
+++ b/navit/maptool/tempfile.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2011 Navit Team
*
diff --git a/navit/maptool/tile.c b/navit/maptool/tile.c
index f0d10332a..695dd6d4e 100644
--- a/navit/maptool/tile.c
+++ b/navit/maptool/tile.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2008 Navit Team
*
@@ -334,12 +334,21 @@ void tile_write_item_to_tile(struct tile_info *info, struct item_bin *ib, FILE *
}
void tile_write_item_minmax(struct tile_info *info, struct item_bin *ib, FILE *reference, int min, int max) {
+ /*TODO: make slice_trigger and slice_target configurable by commandline parameter.
+ * bonus: find out why there is a 'min' parameter here
+ */
+ int slice_trigger = 4;
+ int slice_target = 7;
struct rect r;
char buffer[1024];
bbox((struct coord *)(ib+1), ib->clen/2, &r);
buffer[0]='\0';
tile(&r, info->suffix, buffer, max, overlap, NULL);
- tile_write_item_to_tile(info, ib, reference, buffer);
+ if((ib->type >= type_area) && (ib->type != type_poly_water_tiled) && (tile_len(buffer) < slice_trigger)) {
+ itembin_nicer_slicer(info, ib, reference, buffer, slice_target);
+ } else {
+ tile_write_item_to_tile(info, ib, reference, buffer);
+ }
}
int add_aux_tile(struct zip_info *zip_info, char *name, char *filename, int size) {
diff --git a/navit/maptool/zip.c b/navit/maptool/zip.c
index 2538e2e3b..d912c0073 100644
--- a/navit/maptool/zip.c
+++ b/navit/maptool/zip.c
@@ -1,4 +1,4 @@
-/**
+/*
* Navit, a modular navigation system.
* Copyright (C) 2005-2008 Navit Team
*