summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--navit/file.c65
-rw-r--r--navit/file.h12
-rw-r--r--navit/log.c44
-rw-r--r--navit/log.h30
-rw-r--r--navit/map/binfile/binfile.c39
-rw-r--r--navit/map/mg/map.c2
-rw-r--r--navit/map/mg/tree.c6
-rw-r--r--navit/map/shapefile/shapefile.c2
-rw-r--r--navit/navit.c2
-rw-r--r--navit/transform.c24
-rw-r--r--navit/transform.h3
-rw-r--r--navit/vehicle.c59
12 files changed, 222 insertions, 66 deletions
diff --git a/navit/file.c b/navit/file.c
index 427d25da9..29288c964 100644
--- a/navit/file.c
+++ b/navit/file.c
@@ -33,6 +33,7 @@
#include "debug.h"
#include "cache.h"
#include "file.h"
+#include "atom.h"
#include "config.h"
#ifndef O_LARGEFILE
@@ -57,7 +58,7 @@ struct file_cache_id {
} __attribute__ ((packed));
struct file *
-file_create(char *name)
+file_create(char *name, enum file_flags flags)
{
struct stat stat;
struct file *file= g_new0(struct file,1);
@@ -72,6 +73,9 @@ file_create(char *name)
file->size=stat.st_size;
dbg(1,"size=%Ld\n", file->size);
file->name = g_strdup(name);
+ file->name_id = (int)atom(name);
+ if (file_cache && !(flags & file_flag_nocache))
+ file->cache=1;
dbg_assert(file != NULL);
return file;
}
@@ -141,10 +145,11 @@ int file_mkdir(char *name, int pflag)
int
file_mmap(struct file *file)
{
-#if defined(_WIN32) || defined(__CEGCC__)
- file->begin = (char*)mmap_readonly_win32( file->name, &file->map_handle, &file->map_file );
+ int mmap_size=file->size+1024*1024;
+#ifdef HAVE_API_WIN32_BASE
+ file->begin = (char*)mmap_readonly_win32( file->name, &file->map_handle, &file->map_file );
#else
- file->begin=mmap(NULL, file->size, PROT_READ|PROT_WRITE, MAP_PRIVATE, file->fd, 0);
+ file->begin=mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, file->fd, 0);
dbg_assert(file->begin != NULL);
if (file->begin == (void *)0xffffffff) {
perror("mmap");
@@ -152,6 +157,7 @@ file_mmap(struct file *file)
}
#endif
dbg_assert(file->begin != (void *)0xffffffff);
+ file->mmap_end=file->begin+mmap_size;
file->end=file->begin+file->size;
return 1;
@@ -218,7 +224,7 @@ int
file_get_contents(char *name, unsigned char **buffer, int *size)
{
struct file *file;
- file=file_create(name);
+ file=file_create(name, 0);
if (!file)
return 0;
*size=file_size(file);
@@ -294,9 +300,13 @@ file_data_read_compressed(struct file *file, long long offset, int size, int siz
void
file_data_free(struct file *file, unsigned char *data)
{
- if (file->begin && data >= file->begin && data < file->end)
- return;
- if (file_cache) {
+ if (file->begin) {
+ if (data == file->begin)
+ return;
+ if (data >= file->begin && data < file->end)
+ return;
+ }
+ if (file->cache && data) {
cache_entry_destroy(file_cache, data);
} else
g_free(data);
@@ -358,7 +368,7 @@ file_closedir(void *hnd)
}
struct file *
-file_create_caseinsensitive(char *name)
+file_create_caseinsensitive(char *name, enum file_flags flags)
{
char dirname[strlen(name)+1];
char *filename;
@@ -366,7 +376,7 @@ file_create_caseinsensitive(char *name)
void *d;
struct file *ret;
- ret=file_create(name);
+ ret=file_create(name, flags);
if (ret)
return ret;
@@ -384,7 +394,7 @@ file_create_caseinsensitive(char *name)
while ((filename=file_readdir(d))) {
if (!strcasecmp(filename, p)) {
strcpy(p, filename);
- ret=file_create(dirname);
+ ret=file_create(dirname, flags);
if (ret)
break;
}
@@ -464,20 +474,31 @@ file_get_param(struct file *file, struct param_list *param, int count)
}
int
-file_version(struct file *file, int byname)
+file_version(struct file *file, int mode)
{
-#ifndef __CEGCC__
+#ifndef HAVE_API_WIN32_BASE
struct stat st;
int error;
- if (byname)
- error=stat(file->name, &st);
- else
- error=fstat(file->fd, &st);
- if (error || !file->version || file->mtime != st.st_mtime || file->ctime != st.st_ctime) {
- file->mtime=st.st_mtime;
- file->ctime=st.st_ctime;
- file->version++;
- dbg(0,"%s now version %d\n", file->name, file->version);
+ if (mode == 3) {
+ long long size=lseek(file->fd, 0, SEEK_END);
+ if (file->begin && file->begin+size > file->mmap_end) {
+ file->version++;
+ } else {
+ file->size=size;
+ if (file->begin)
+ file->end=file->begin+file->size;
+ }
+ } else {
+ if (mode == 2)
+ error=stat(file->name, &st);
+ else
+ error=fstat(file->fd, &st);
+ if (error || !file->version || file->mtime != st.st_mtime || file->ctime != st.st_ctime) {
+ file->mtime=st.st_mtime;
+ file->ctime=st.st_ctime;
+ file->version++;
+ dbg(1,"%s now version %d\n", file->name, file->version);
+ }
}
return file->version;
#else
diff --git a/navit/file.h b/navit/file.h
index a8003263d..67944bc8b 100644
--- a/navit/file.h
+++ b/navit/file.h
@@ -33,6 +33,7 @@ struct file {
struct file *next;
unsigned char *begin;
unsigned char *end;
+ unsigned char *mmap_end;
long long size;
int name_id;
int fd;
@@ -48,18 +49,25 @@ struct file {
char *name;
FILE *stdfile;
int special;
+ int cache;
+};
+
+enum file_flags {
+ file_flag_nocache=1,
};
/* prototypes */
+enum file_flags;
struct file;
struct file_wordexp;
struct param_list;
-struct file *file_create(char *name);
+struct file *file_create(char *name, enum file_flags flags);
int file_is_dir(char *name);
long long file_size(struct file *file);
int file_mkdir(char *name, int pflag);
int file_mmap(struct file *file);
unsigned char *file_data_read(struct file *file, long long offset, int size);
+unsigned char *file_data_read_special(struct file *file, int size, int *size_ret);
unsigned char *file_data_read_all(struct file *file);
int file_data_write(struct file *file, long long offset, int size, unsigned char *data);
int file_get_contents(char *name, unsigned char **buffer, int *size);
@@ -71,7 +79,7 @@ void file_unmap(struct file *f);
void *file_opendir(char *dir);
char *file_readdir(void *hnd);
void file_closedir(void *hnd);
-struct file *file_create_caseinsensitive(char *name);
+struct file *file_create_caseinsensitive(char *name, enum file_flags flags);
void file_destroy(struct file *f);
struct file_wordexp *file_wordexp_new(const char *pattern);
int file_wordexp_get_count(struct file_wordexp *wexp);
diff --git a/navit/log.c b/navit/log.c
index 95b34e677..b12d2ba07 100644
--- a/navit/log.c
+++ b/navit/log.c
@@ -128,7 +128,7 @@ log_close(struct log *this_)
}
static void
-log_flush(struct log *this_)
+log_flush(struct log *this_, enum log_flags flags)
{
long pos;
if (this_->lazy && !this_->f) {
@@ -145,6 +145,12 @@ log_flush(struct log *this_)
this_->empty=0;
}
fwrite(this_->data.data, 1, this_->data.len, this_->f);
+#ifndef HAVE_API_WIN32_BASE
+ if (flags & log_flag_truncate) {
+ pos=ftell(this_->f);
+ ftruncate(fileno(this_->f), pos);
+ }
+#endif
if (this_->trailer.len) {
pos=ftell(this_->f);
if (pos > 0) {
@@ -152,11 +158,14 @@ log_flush(struct log *this_)
fseek(this_->f, pos, SEEK_SET);
}
}
-
+ if (flags & log_flag_keep_pointer)
+ fseek(this_->f, -this_->data.len, SEEK_CUR);
fflush(this_->f);
- g_free(this_->data.data);
- this_->data.data=NULL;
- this_->data.max_len=this_->data.len=0;
+ if (!(flags & log_flag_keep_buffer)) {
+ g_free(this_->data.data);
+ this_->data.data=NULL;
+ this_->data.max_len=this_->data.len=0;
+ }
log_set_last_flush(this_);
}
@@ -170,7 +179,7 @@ log_flush_required(struct log *this_)
static void
log_change(struct log *this_)
{
- log_flush(this_);
+ log_flush(this_,0);
log_close(this_);
expand_filenames(this_);
if (! this_->lazy)
@@ -195,7 +204,7 @@ log_timer(struct log *this_)
delta=(tv.tv_sec-this_->last_flush.tv_sec)*1000+(tv.tv_usec-this_->last_flush.tv_usec)/1000;
dbg(1,"delta=%d flush_time=%d\n", delta, this_->flush_time);
if (this_->flush_time && delta >= this_->flush_time*1000)
- log_flush(this_);
+ log_flush(this_,0);
}
int
@@ -273,13 +282,15 @@ log_set_trailer(struct log *this_, char *data, int len)
}
void
-log_write(struct log *this_, char *data, int len)
+log_write(struct log *this_, char *data, int len, enum log_flags flags)
{
dbg(1,"enter\n");
if (log_change_required(this_)) {
dbg(1,"log_change");
log_change(this_);
}
+ if (flags & log_flag_replace_buffer)
+ this_->data.len=0;
if (this_->data.len + len > this_->data.max_len) {
dbg(2,"overflow\n");
this_->data.max_len+=16384;
@@ -287,10 +298,19 @@ log_write(struct log *this_, char *data, int len)
}
memcpy(this_->data.data+this_->data.len, data, len);
this_->data.len+=len;
- if (log_flush_required(this_))
- log_flush(this_);
+ if (log_flush_required(this_) || (flags & log_flag_force_flush))
+ log_flush(this_, flags);
}
+void *
+log_get_buffer(struct log *this_, int *len)
+{
+ if (len)
+ *len=this_->data.len;
+ return this_->data.data;
+}
+
+
void
log_printf(struct log *this_, char *fmt, ...)
{
@@ -302,7 +322,7 @@ log_printf(struct log *this_, char *fmt, ...)
// Format the string and write it to the log
size = vsnprintf(buffer, LOG_BUFFER_SIZE, fmt, ap);
- log_write(this_, buffer, size);
+ log_write(this_, buffer, size, 0);
va_end(ap);
}
@@ -312,7 +332,7 @@ log_destroy(struct log *this_)
{
callback_destroy(this_->timer_callback);
event_remove_timeout(this_->timer);
- log_flush(this_);
+ log_flush(this_,0);
log_close(this_);
g_free(this_);
}
diff --git a/navit/log.h b/navit/log.h
index edb4433f2..8a9f073f1 100644
--- a/navit/log.h
+++ b/navit/log.h
@@ -19,25 +19,33 @@
#ifndef NAVIT_LOG_H
#define NAVIT_LOG_H
+#define LOG_BUFFER_SIZE 256
+/**
+ * printf-style writing to the log file. A buffer of LOG_BUFFER_SIZE
+ * bytes is preallocated for the complete format message, longer
+ * messages will be truncated.
+ */
+
+enum log_flags {
+ log_flag_replace_buffer=1,
+ log_flag_force_flush=2,
+ log_flag_keep_pointer=4,
+ log_flag_keep_buffer=8,
+ log_flag_truncate=16,
+};
/* prototypes */
enum attr_type;
+enum log_flags;
struct attr;
struct attr_iter;
struct log;
int log_get_attr(struct log *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
-struct log *log_new(struct attr * parent,struct attr **attrs);
+struct log *log_new(struct attr *parent, struct attr **attrs);
void log_set_header(struct log *this_, char *data, int len);
void log_set_trailer(struct log *this_, char *data, int len);
-void log_write(struct log *this_, char *data, int len);
-void log_destroy(struct log *this_);
-
-#define LOG_BUFFER_SIZE 256
-/**
- * printf-style writing to the log file. A buffer of LOG_BUFFER_SIZE
- * bytes is preallocated for the complete format message, longer
- * messages will be truncated.
- */
+void log_write(struct log *this_, char *data, int len, enum log_flags flags);
+void *log_get_buffer(struct log *this_, int *len);
void log_printf(struct log *this_, char *fmt, ...);
-
+void log_destroy(struct log *this_);
/* end of prototypes */
#endif
diff --git a/navit/map/binfile/binfile.c b/navit/map/binfile/binfile.c
index c6256a984..8622391e8 100644
--- a/navit/map/binfile/binfile.c
+++ b/navit/map/binfile/binfile.c
@@ -279,7 +279,15 @@ binfile_coord_get(void *priv_data, struct coord *c, int count)
{
struct map_rect_priv *mr=priv_data;
struct tile *t=mr->t;
- int ret=0;
+ int max,ret=0;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ max=(t->pos_attr_start-t->pos_coord)/2;
+ if (count > max)
+ count=max;
+ memcpy(c, t->pos_coord, count*sizeof(struct coord));
+ t->pos_coord+=count*2;
+ ret=count;
+#else
dbg(2,"binfile_coord_get %d\n",count);
while (count--) {
dbg(2,"%p vs %p\n", t->pos_coord, t->pos_attr_start);
@@ -290,6 +298,7 @@ binfile_coord_get(void *priv_data, struct coord *c, int count)
c++;
ret++;
}
+#endif
return ret;
}
@@ -771,6 +780,8 @@ map_rect_new_binfile(struct map_priv *map, struct map_selection *sel)
binfile_check_version(map);
dbg(1,"map_rect_new_binfile\n");
+ if (!map->fi)
+ return NULL;
mr=g_new0(struct map_rect_priv, 1);
mr->m=map;
mr->sel=sel;
@@ -780,7 +791,8 @@ map_rect_new_binfile(struct map_priv *map, struct map_selection *sel)
if (map->eoc)
push_zipfile_tile(mr, map->zip_members-1);
else {
- unsigned char *d=file_data_read(map->fi, 0, map->fi->size);
+ unsigned char *d;
+ d=file_data_read(map->fi, 0, map->fi->size);
t.start=(int *)d;
t.end=(int *)(d+map->fi->size);
t.zipfile_num=0;
@@ -1271,14 +1283,19 @@ map_binfile_open(struct map_priv *m)
struct attr attr;
dbg(1,"file_create %s\n", m->filename);
- m->fi=file_create(m->filename);
+ m->fi=file_create(m->filename, 0);
if (! m->fi) {
dbg(0,"Failed to load '%s'\n", m->filename);
return 0;
}
if (m->check_version)
- m->version=file_version(m->fi, m->check_version == 2);
+ m->version=file_version(m->fi, m->check_version);
magic=(int *)file_data_read(m->fi, 0, 4);
+ if (!magic) {
+ file_destroy(m->fi);
+ m->fi=NULL;
+ return 0;
+ }
*magic = le32_to_cpu(*magic);
if (*magic == zip_lfh_sig) {
if ((m->eoc=binfile_read_eoc(m->fi)) && binfile_get_index(m) && (first_cd=binfile_read_cd(m, 0, 0))) {
@@ -1289,9 +1306,11 @@ map_binfile_open(struct map_priv *m)
file_data_free(m->fi, (unsigned char *)first_cd);
} else {
dbg(0,"invalid file format for '%s'\n", m->filename);
+ file_destroy(m->fi);
+ m->fi=NULL;
return 0;
}
- } else
+ } else
file_mmap(m->fi);
file_data_free(m->fi, (unsigned char *)magic);
m->cachedir="/tmp/navit";
@@ -1330,12 +1349,14 @@ map_binfile_destroy(struct map_priv *m)
static void
binfile_check_version(struct map_priv *m)
{
- int version;
+ int version=-1;
if (!m->check_version)
return;
- version=file_version(m->fi, m->check_version == 2);
+ if (m->fi)
+ version=file_version(m->fi, m->check_version);
if (version != m->version) {
- map_binfile_close(m);
+ if (m->fi)
+ map_binfile_close(m);
map_binfile_open(m);
}
}
@@ -1364,7 +1385,7 @@ map_new_binfile(struct map_methods *meth, struct attr **attrs)
check_version=attr_search(attrs, NULL, attr_check_version);
if (check_version)
m->check_version=check_version->u.num;
- if (!map_binfile_open(m)) {
+ if (!map_binfile_open(m) && !m->check_version) {
map_binfile_destroy(m);
m=NULL;
} else {
diff --git a/navit/map/mg/map.c b/navit/map/mg/map.c
index 976d6850e..61099f342 100644
--- a/navit/map/mg/map.c
+++ b/navit/map/mg/map.c
@@ -587,7 +587,7 @@ map_new_mg(struct map_methods *meth, struct attr **attrs)
for (i = 0 ; i < file_end ; i++) {
if (file[i]) {
filename=g_strdup_printf("%s/%s", m->dirname, file[i]);
- m->file[i]=file_create_caseinsensitive(filename);
+ m->file[i]=file_create_caseinsensitive(filename, 0);
if (! m->file[i]) {
maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply);
if (! maybe_missing)
diff --git a/navit/map/mg/tree.c b/navit/map/mg/tree.c
index 9c2bb08e5..ef542bc20 100644
--- a/navit/map/mg/tree.c
+++ b/navit/map/mg/tree.c
@@ -144,12 +144,12 @@ tree_search_hv(char *dirname, char *filename, unsigned int search_h, unsigned in
dbg(1,"enter(%s, %s, 0x%x, 0x%x, %p)\n",dirname, filename, search_h, search_v, result);
sprintf(buffer, "%s/%s.h1", dirname, filename);
- f_idx_h=file_create_caseinsensitive(buffer);
+ f_idx_h=file_create_caseinsensitive(buffer, 0);
if (! f_idx_h)
return 0;
file_mmap(f_idx_h);
sprintf(buffer, "%s/%s.v1", dirname, filename);
- f_idx_v=file_create_caseinsensitive(buffer);
+ f_idx_v=file_create_caseinsensitive(buffer, 0);
dbg(1,"%p %p\n", f_idx_h, f_idx_v);
if (! f_idx_v) {
file_destroy(f_idx_h);
@@ -266,7 +266,7 @@ tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offs
{
char buffer[4096];
sprintf(buffer, "%s/%s", dirname, filename);
- ts->f=file_create_caseinsensitive(buffer);
+ ts->f=file_create_caseinsensitive(buffer, 0);
ts->curr_node=-1;
if (ts->f) {
file_mmap(ts->f);
diff --git a/navit/map/shapefile/shapefile.c b/navit/map/shapefile/shapefile.c
index 41cc37b56..d539863fe 100644
--- a/navit/map/shapefile/shapefile.c
+++ b/navit/map/shapefile/shapefile.c
@@ -479,7 +479,7 @@ map_rect_new_shapefile(struct map_priv *map, struct map_selection *sel)
struct file *file;
int size;
int changed=0;
- if ((file=file_create(dbfmapfile))) {
+ if ((file=file_create(dbfmapfile, 0))) {
size=file_size(file);
data=file_data_read_all(file);
if (data) {
diff --git a/navit/navit.c b/navit/navit.c
index e6038b07d..9c0e805b8 100644
--- a/navit/navit.c
+++ b/navit/navit.c
@@ -1076,7 +1076,7 @@ navit_textfile_debug_log(struct navit *this_, const char *fmt, ...)
if (this_->textfile_debug_log && this_->vehicle) {
str1=g_strdup_vprintf(fmt, ap);
str2=g_strdup_printf("0x%x 0x%x%s%s\n", this_->vehicle->coord.x, this_->vehicle->coord.y, strlen(str1) ? " " : "", str1);
- log_write(this_->textfile_debug_log, str2, strlen(str2));
+ log_write(this_->textfile_debug_log, str2, strlen(str2), 0);
g_free(str2);
g_free(str1);
}
diff --git a/navit/transform.c b/navit/transform.c
index 55e6725d3..a1a1dbb7a 100644
--- a/navit/transform.c
+++ b/navit/transform.c
@@ -1042,6 +1042,30 @@ transform_distance_polyline_sq(struct coord *c, int count, struct coord *ref, st
return dist;
}
+int
+transform_douglas_peucker(struct coord *in, int count, int dist_sq, struct coord *out)
+{
+ int ret=0;
+ int i,d,dmax=0, idx=0;
+ for (i = 1; i < count-1 ; i++) {
+ d=transform_distance_line_sq(&in[0], &in[count-1], &in[i], NULL);
+ if (d > dmax) {
+ idx=i;
+ dmax=d;
+ }
+ }
+ if (dmax > dist_sq) {
+ ret=transform_douglas_peucker(in, idx+1, dist_sq, out)-1;
+ ret+=transform_douglas_peucker(in+idx, count-idx, dist_sq, out+ret);
+ } else {
+ if (count > 0)
+ out[ret++]=in[0];
+ if (count > 1)
+ out[ret++]=in[count-1];
+ }
+ return ret;
+}
+
void
transform_print_deg(double deg)
diff --git a/navit/transform.h b/navit/transform.h
index ee617d72e..c1357ac72 100644
--- a/navit/transform.h
+++ b/navit/transform.h
@@ -49,7 +49,7 @@ void transform_geo_to_cart(struct coord_geo *geo, navit_float a, navit_float b,
void transform_cart_to_geo(struct coord_geo_cart *cart, navit_float a, navit_float b, struct coord_geo *geo);
void transform_utm_to_geo(const double UTMEasting, const double UTMNorthing, int ZoneNumber, int NorthernHemisphere, struct coord_geo *geo);
void transform_datum(struct coord_geo *from, enum map_datum from_datum, struct coord_geo *to, enum map_datum to_datum);
-int transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int unique, int width, int *width_return);
+int transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int mindist, int width, int *width_return);
void transform_reverse(struct transformation *t, struct point *p, struct coord *c);
enum projection transform_get_projection(struct transformation *this_);
void transform_set_projection(struct transformation *this_, enum projection pro);
@@ -81,6 +81,7 @@ int transform_distance_sq(struct coord *c1, struct coord *c2);
int transform_distance_sq_pc(struct pcoord *c1, struct pcoord *c2);
int transform_distance_line_sq(struct coord *l0, struct coord *l1, struct coord *ref, struct coord *lpnt);
int transform_distance_polyline_sq(struct coord *c, int count, struct coord *ref, struct coord *lpnt, int *pos);
+int transform_douglas_peucker(struct coord *in, int count, int dist_sq, struct coord *out);
void transform_print_deg(double deg);
int transform_get_angle_delta(struct coord *c1, struct coord *c2, int dir);
int transform_within_border(struct transformation *this_, struct point *p, int border);
diff --git a/navit/vehicle.c b/navit/vehicle.c
index 5518b04b6..db5babfef 100644
--- a/navit/vehicle.c
+++ b/navit/vehicle.c
@@ -29,6 +29,7 @@
#include "callback.h"
#include "plugin.h"
#include "vehicle.h"
+#include "transform.h"
#include "util.h"
struct vehicle {
@@ -47,7 +48,7 @@ vehicle_log_nmea(struct vehicle *this_, struct log *log)
return;
if (!this_->meth.position_attr_get(this_->priv, attr_position_nmea, &pos_attr))
return;
- log_write(log, pos_attr.u.str, strlen(pos_attr.u.str));
+ log_write(log, pos_attr.u.str, strlen(pos_attr.u.str), 0);
}
static void
@@ -93,7 +94,7 @@ vehicle_log_gpx(struct vehicle *this_, struct log *log)
}
logstr=g_strconcat_printf(logstr,"</trkpt>\n");
callback_list_call_attr_1(this_->cbl, attr_log_gpx, &logstr);
- log_write(log, logstr, strlen(logstr));
+ log_write(log, logstr, strlen(logstr), 0);
g_free(logstr);
}
@@ -108,7 +109,57 @@ vehicle_log_textfile(struct vehicle *this_, struct log *log)
return;
logstr=g_strdup_printf("%f %f type=trackpoint\n", pos_attr.u.coord_geo->lng, pos_attr.u.coord_geo->lat);
callback_list_call_attr_1(this_->cbl, attr_log_textfile, &logstr);
- log_write(log, logstr, strlen(logstr));
+ log_write(log, logstr, strlen(logstr), 0);
+}
+
+static void
+vehicle_log_binfile(struct vehicle *this_, struct log *log)
+{
+ struct attr pos_attr;
+ int *buffer;
+ int *buffer_new;
+ int len,limit=1024,done=0,radius=25;
+ struct coord c;
+ enum log_flags flags;
+
+ if (!this_->meth.position_attr_get)
+ return;
+ if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
+ return;
+ transform_from_geo(projection_mg, pos_attr.u.coord_geo, &c);
+ if (!c.x || !c.y)
+ return;
+ while (!done) {
+ buffer=log_get_buffer(log, &len);
+ if (! buffer || !len) {
+ buffer_new=g_malloc(5*sizeof(int));
+ buffer_new[0]=2;
+ buffer_new[1]=type_track;
+ buffer_new[2]=0;
+ } else {
+ buffer_new=g_malloc((buffer[0]+3)*sizeof(int));
+ memcpy(buffer_new, buffer, (buffer[0]+1)*sizeof(int));
+ }
+ dbg(1,"c=0x%x,0x%x\n",c.x,c.y);
+ buffer_new[buffer_new[0]+1]=c.x;
+ buffer_new[buffer_new[0]+2]=c.y;
+ buffer_new[0]+=2;
+ buffer_new[2]+=2;
+ if (buffer_new[2] > limit) {
+ int count=buffer_new[2]/2;
+ struct coord out[count];
+ struct coord *in=(struct coord *)(buffer_new+3);
+ int count_out=transform_douglas_peucker(in, count, radius, out);
+ memcpy(in, out, count_out*2*sizeof(int));
+ buffer_new[0]+=(count_out-count)*2;
+ buffer_new[2]+=(count_out-count)*2;
+ flags=log_flag_replace_buffer|log_flag_force_flush|log_flag_truncate;
+ } else {
+ flags=log_flag_replace_buffer|log_flag_keep_pointer|log_flag_keep_buffer|log_flag_force_flush;
+ done=1;
+ }
+ log_write(log, (char *)buffer_new, (buffer_new[0]+1)*sizeof(int), flags);
+ }
}
static int
@@ -138,6 +189,8 @@ vehicle_add_log(struct vehicle *this_, struct log *log)
char *header = "type=track\n";
log_set_header(log, header, strlen(header));
cb=callback_new_attr_2(callback_cast(vehicle_log_textfile), attr_position_coord_geo, this_, log);
+ } else if (!strcmp(type_attr.u.str, "binfile")) {
+ cb=callback_new_attr_2(callback_cast(vehicle_log_binfile), attr_position_coord_geo, this_, log);
} else
return 1;
callback_list_add(this_->cbl, cb);