summaryrefslogtreecommitdiff
path: root/destination.c
diff options
context:
space:
mode:
Diffstat (limited to 'destination.c')
-rw-r--r--destination.c622
1 files changed, 622 insertions, 0 deletions
diff --git a/destination.c b/destination.c
new file mode 100644
index 00000000..9cced769
--- /dev/null
+++ b/destination.c
@@ -0,0 +1,622 @@
+#include <gtk/gtk.h>
+#include "coord.h"
+#include "transform.h"
+#include "block.h"
+#include "data_window.h"
+#include "country.h"
+#include "town.h"
+#include "street.h"
+#include "street_name.h"
+#include "gui/gtk/gtkeyboard.h"
+#include "cursor.h"
+#include "route.h"
+#include "statusbar.h"
+#include "unistd.h"
+#include "destination.h"
+#include "coord.h"
+#include "container.h"
+
+extern gint track_focus(gpointer data);
+
+
+
+GtkWidget *entry_country, *entry_postal, *entry_city, *entry_district;
+GtkWidget *entry_street, *entry_number;
+GtkWidget *listbox;
+int row_count=8;
+
+int selected;
+
+struct search_param {
+ struct map_data *map_data;
+ const char *country;
+ GHashTable *country_hash;
+ const char *town;
+ GHashTable *town_hash;
+ GHashTable *district_hash;
+ const char *street;
+ GHashTable *street_hash;
+ const char *number;
+ int number_low, number_high;
+ GtkWidget *clist;
+ int count;
+} search_param2;
+
+struct destination {
+ struct town *town;
+ struct street_name *street_name;
+ struct coord *c;
+};
+
+struct country_list *country_list;
+
+static void
+select_row(GtkCList *clist, int row, int column, GdkEventButton *event, struct data_window *win)
+{
+ selected=row;
+ printf("Selected %d\n", row);
+}
+
+int
+destination_set(struct container *co, enum destination_type type, char *text, struct coord *pos)
+{
+ route_set_position(co->route, cursor_pos_get(co->cursor));
+ route_set_destination(co->route, pos);
+ graphics_redraw(co);
+ if (co->statusbar && co->statusbar->statusbar_route_update)
+ co->statusbar->statusbar_route_update(co->statusbar, co->route);
+ return 0;
+}
+
+int
+get_position(struct search_param *search, struct coord *c)
+{
+ struct destination *dest;
+
+ if (selected == -1)
+ selected=0;
+ dest=gtk_clist_get_row_data (GTK_CLIST(search->clist), selected);
+
+ printf("row %d dest %p dest:0x%lx,0x%lx\n", selected, dest, dest->c->x, dest->c->y);
+ *c=*dest->c;
+ return 0;
+}
+
+void button_map(GtkWidget *widget, struct container *co)
+{
+ unsigned long scale;
+ struct coord c;
+
+ if (!get_position(&search_param2, &c)) {
+ graphics_set_view(co, &c.x, &c.y, NULL);
+ }
+}
+
+void button_destination(GtkWidget *widget, struct container *co)
+{
+ struct coord c;
+
+ if (!get_position(&search_param2, &c)) {
+ route_set_position(co->route, cursor_pos_get(co->cursor));
+ route_set_destination(co->route, &c);
+ graphics_redraw(co);
+ }
+}
+
+struct dest_town {
+ int country;
+ int assoc;
+ char *name;
+ char postal_code[16];
+ struct town town;
+};
+
+guint
+destination_town_hash(gconstpointer key)
+{
+ const struct dest_town *hash=key;
+ gconstpointer hashkey=(gconstpointer)(hash->country^hash->assoc);
+ return g_direct_hash(hashkey);
+}
+
+gboolean
+destination_town_equal(gconstpointer a, gconstpointer b)
+{
+ const struct dest_town *t_a=a;
+ const struct dest_town *t_b=b;
+ if (t_a->assoc == t_b->assoc && t_a->country == t_b->country) {
+ if (t_a->name && t_b->name && strcmp(t_a->name, t_b->name))
+ return FALSE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+GHashTable *
+destination_town_new(void)
+{
+ return g_hash_table_new_full(destination_town_hash, destination_town_equal, NULL, g_free);
+}
+
+void
+destination_town_set(const struct dest_town *town, char **rows, int full)
+{
+ char country[32];
+ struct country *cou;
+ if ((cou=country_get_by_id(town->country))) {
+ rows[1]=cou->car;
+ } else {
+ sprintf(country,"(%d)", town->country);
+ rows[1]=country;
+ }
+ if (full) {
+ rows[4]=(char *)(town->town.postal_code2);
+ rows[5]=g_convert(town->town.name,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
+ if (town->town.district[0])
+ rows[6]=g_convert(town->town.district,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
+ else
+ rows[6]=NULL;
+ } else {
+ rows[4]=(char *)(town->postal_code);
+ rows[5]=g_convert(town->name,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
+ }
+}
+
+void
+destination_town_show(gpointer key, gpointer value, gpointer user_data)
+{
+ struct dest_town *town=value;
+ struct search_param *search=(struct search_param *)user_data;
+ char *rows[9]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+ int row;
+
+ if (search->count > 0) {
+ struct destination *dest=g_new(struct destination, 1);
+ dest->town=&town->town;
+ dest->street_name=NULL;
+ dest->c=town->town.c;
+ destination_town_set(town, rows, 0);
+ row=gtk_clist_append(GTK_CLIST(search->clist), rows);
+ printf("town row %d %p dest:0x%lx,0x%lx\n", row, dest, dest->c->x, dest->c->y);
+ gtk_clist_set_row_data(GTK_CLIST(search->clist), row, dest);
+ search->count--;
+ }
+}
+
+GHashTable *
+destination_country_new(void)
+{
+ return g_hash_table_new_full(NULL, NULL, NULL, g_free);
+}
+
+int
+destination_country_add(struct country *cou, void *data)
+{
+ struct search_param *search=data;
+ struct country *cou2;
+
+ void *first;
+ first=g_hash_table_lookup(search->country_hash, (void *)(cou->id));
+ if (! first) {
+ cou2=g_new(struct country, 1);
+ *cou2=*cou;
+ g_hash_table_insert(search->country_hash, (void *)(cou->id), cou2);
+ }
+ return 0;
+}
+
+void
+destination_country_show(gpointer key, gpointer value, gpointer user_data)
+{
+ struct country *cou=value;
+ struct search_param *search=(struct search_param *)user_data;
+ char *rows[9]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+ if (search->count > 0) {
+ rows[0]=cou->name;
+ rows[1]=cou->car;
+ rows[2]=cou->iso2;
+ rows[3]=cou->iso3;
+ gtk_clist_append(GTK_CLIST(search->clist), rows);
+ search->count--;
+ }
+}
+
+int
+destination_town_add(struct town *town, void *data)
+{
+ struct search_param *search=data;
+ struct dest_town *first;
+
+ struct dest_town cmp;
+ char *zip1, *zip2;
+
+ if (town->id == 0x1d546b7e) {
+ printf("found\n");
+ }
+ cmp.country=town->country;
+ cmp.assoc=town->street_assoc;
+ cmp.name=town->name;
+ first=g_hash_table_lookup(search->town_hash, &cmp);
+ if (! first) {
+ first=g_new(struct dest_town, 1);
+ first->country=cmp.country;
+ first->assoc=cmp.assoc;
+ strcpy(first->postal_code, town->postal_code2);
+ first->name=town->name;
+ first->town=*town;
+ g_hash_table_insert(search->town_hash, first, first);
+ } else {
+ zip1=town->postal_code2;
+ zip2=first->postal_code;
+ while (*zip1 && *zip2) {
+ if (*zip1 != *zip2) {
+ while (*zip2) {
+ *zip2++='.';
+ }
+ break;
+ }
+ zip1++;
+ zip2++;
+ }
+ }
+ cmp.name=NULL;
+ cmp.assoc=town->id;
+ first=g_hash_table_lookup(search->district_hash, &cmp);
+ if (! first) {
+ first=g_new(struct dest_town, 1);
+ first->country=cmp.country;
+ first->assoc=cmp.assoc;
+ first->name=NULL;
+ first->town=*town;
+ g_hash_table_insert(search->district_hash, first, first);
+ }
+ return 0;
+}
+
+void
+destination_town_search(gpointer key, gpointer value, gpointer user_data)
+{
+ struct country *cou=value;
+ struct search_param *search=(struct search_param *)user_data;
+ town_search_by_name(search->map_data, cou->id, search->town, 1, destination_town_add, search);
+
+}
+
+GHashTable *
+destination_street_new(void)
+{
+ return g_hash_table_new_full(NULL, NULL, NULL, g_free);
+}
+
+
+int
+destination_street_add(struct street_name *name, void *data)
+{
+ struct search_param *search=data;
+ struct street_name *name2;
+
+ name2=g_new(struct street_name, 1);
+ *name2=*name;
+ g_hash_table_insert(search->street_hash, name2, name2);
+ return 0;
+}
+
+static int
+number_partial(int search, int ref, int ext)
+{
+ int max=1;
+
+ printf("number_partial(%d,%d,%d)", search, ref, ext);
+ if (ref >= 10)
+ max=10;
+ if (ref >= 100)
+ max=100;
+ if (ref >= 1000)
+ max=1000;
+ while (search < max) {
+ search*=10;
+ search+=ext;
+ }
+ printf("max=%d result=%d\n", max, search);
+ return search;
+}
+
+static int
+check_number(int low, int high, int s_low, int s_high)
+{
+ printf("check_number(%d,%d,%d,%d)\n", low, high, s_low, s_high);
+ if (low <= s_high && high >= s_low)
+ return 1;
+ if (s_low == s_high) {
+ if (low <= number_partial(s_high, high, 9) && high >= number_partial(s_low, low, 0))
+ return 1;
+ }
+ printf("return 0\n");
+ return 0;
+}
+
+void
+destination_street_show_common(gpointer key, gpointer value, gpointer user_data, int number)
+{
+ struct street_name *name=value;
+ struct search_param *search=(struct search_param *)user_data;
+ char *utf8;
+ struct dest_town cmp;
+ struct dest_town *town;
+ int row;
+ char buffer[32];
+ char *rows[9]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+ struct street_name_info info;
+ struct street_name_number_info num_info;
+
+ name->tmp_len=name->aux_len;
+ name->tmp_data=name->aux_data;
+ while (street_name_get_info(&info, name) && search->count > 0) {
+ struct destination *dest;
+ cmp.country=info.country;
+ cmp.assoc=info.dist;
+ cmp.name=NULL;
+ town=g_hash_table_lookup(search->district_hash, &cmp);
+ printf("town=%p\n", town);
+ if (town) {
+ destination_town_set(town, rows, 1);
+ utf8=g_convert(name->name2,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
+ rows[4]=utf8;
+ if (number) {
+ info.tmp_len=info.aux_len;
+ info.tmp_data=info.aux_data;
+ while (street_name_get_number_info(&num_info, &info) && search->count > 0) {
+ dest=g_new(struct destination, 1);
+ dest->town=&town->town;
+ dest->street_name=name;
+ dest->c=num_info.c;
+ if (check_number(num_info.first, num_info.last, search->number_low, search->number_high)) {
+ if (num_info.first == num_info.last)
+ sprintf(buffer,"%d",num_info.first);
+ else
+ sprintf(buffer,"%d-%d",num_info.first,num_info.last);
+ rows[8]=buffer;
+ printf("'%s','%s','%s','%s','%s','%s'\n", rows[0],rows[1],rows[2],rows[3],rows[4],rows[5]);
+ row=gtk_clist_append(GTK_CLIST(listbox), rows);
+ gtk_clist_set_row_data(GTK_CLIST(listbox), row, dest);
+ search->count--;
+ }
+ }
+ } else {
+ row=gtk_clist_append(GTK_CLIST(listbox), rows);
+ dest=g_new(struct destination, 1);
+ dest->town=&town->town;
+ dest->street_name=name;
+ dest->c=info.c;
+ gtk_clist_set_row_data(GTK_CLIST(listbox), row, dest);
+ search->count--;
+ }
+ g_free(utf8);
+ } else {
+ printf("Town for '%s' not found\n", name->name2);
+ }
+ }
+}
+
+void
+destination_street_show(gpointer key, gpointer value, gpointer user_data)
+{
+ destination_street_show_common(key, value, user_data, 0);
+}
+
+void
+destination_street_show_number(gpointer key, gpointer value, gpointer user_data)
+{
+ destination_street_show_common(key, value, user_data, 1);
+}
+
+void
+destination_street_search(gpointer key, gpointer value, gpointer user_data)
+{
+ const struct dest_town *town=value;
+ struct search_param *search=(struct search_param *)user_data;
+ street_name_search(search->map_data, town->country, town->assoc, search->street, 1, destination_street_add, search);
+}
+
+
+
+void changed(GtkWidget *widget, struct search_param *search)
+{
+ const char *str;
+ char *empty[9]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+ char *dash;
+
+ gtk_clist_freeze(GTK_CLIST(listbox));
+ gtk_clist_clear(GTK_CLIST(listbox));
+
+ selected=-1;
+
+ search->count=row_count;
+
+ str=gtk_entry_get_text(GTK_ENTRY(widget));
+
+ if (widget == entry_country) {
+ if (search->country_hash) g_hash_table_destroy(search->country_hash);
+ search->country_hash=NULL;
+ }
+ if (widget == entry_country || widget == entry_city) {
+ if (search->town_hash) g_hash_table_destroy(search->town_hash);
+ if (search->district_hash) g_hash_table_destroy(search->district_hash);
+ search->town_hash=NULL;
+ search->district_hash=NULL;
+ }
+
+ if (widget == entry_country || widget == entry_city || widget == entry_street) {
+ if (search->street_hash) g_hash_table_destroy(search->street_hash);
+ search->street_hash=NULL;
+ }
+
+ if (widget == entry_country) {
+ search->country_hash=destination_country_new();
+ search->country=str;
+ country_search_by_name(str, 1, destination_country_add, search);
+ country_search_by_car(str, 1, destination_country_add, search);
+ country_search_by_iso2(str, 1, destination_country_add, search);
+ country_search_by_iso3(str, 1, destination_country_add, search);
+ g_hash_table_foreach(search->country_hash, destination_country_show, search);
+ }
+ if (widget == entry_city) {
+ printf("Ort: '%s'\n", str);
+ if (strlen(str) > 1) {
+ search->town=str;
+ search->town_hash=destination_town_new();
+ search->district_hash=destination_town_new();
+ g_hash_table_foreach(search->country_hash, destination_town_search, search);
+ g_hash_table_foreach(search->town_hash, destination_town_show, search);
+ }
+ }
+ if (widget == entry_street) {
+ printf("Street: '%s'\n", str);
+ search->street=str;
+ search->street_hash=destination_street_new();
+ g_hash_table_foreach(search->town_hash, destination_street_search, search);
+ g_hash_table_foreach(search->street_hash, destination_street_show, search);
+ }
+ if (widget == entry_number) {
+ char buffer[strlen(str)+1];
+ strcpy(buffer, str);
+ search->number=str;
+ dash=index(buffer,'-');
+ if (dash) {
+ *dash++=0;
+ search->number_low=atoi(buffer);
+ if (strlen(str))
+ search->number_high=atoi(dash);
+ else
+ search->number_high=10000;
+ } else {
+ if (!strlen(str)) {
+ search->number_low=0;
+ search->number_high=10000;
+ } else {
+ search->number_low=atoi(str);
+ search->number_high=atoi(str);
+ }
+ }
+ g_hash_table_foreach(search->street_hash, destination_street_show_number, search);
+ }
+ while (search->count-- > 0) {
+ gtk_clist_append(GTK_CLIST(listbox), empty);
+ }
+ gtk_clist_columns_autosize (GTK_CLIST(listbox));
+ gtk_clist_thaw(GTK_CLIST(listbox));
+}
+
+int destination_address(struct container *co)
+{
+ GtkWidget *window2, *keyboard, *vbox, *table;
+ GtkWidget *label_country;
+ GtkWidget *label_postal, *label_city, *label_district;
+ GtkWidget *label_street, *label_number;
+ GtkWidget *hseparator1,*hseparator2;
+ GtkWidget *button1,*button2;
+ init_keyboard_stuff((char *) NULL);
+ int handlerid;
+ int i;
+ gchar *text[9]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+ struct search_param *search=&search_param2;
+
+#if 0
+ if (co->cursor) {
+ struct coord *c;
+ struct route_info *rt;
+ struct street_str *st;
+ struct block_info *blk;
+ struct street_name name;
+ struct town town;
+
+ c=cursor_pos_get(co->cursor);
+ rt=route_find_nearest_street(co->map_data, c);
+ st=route_info_get_street(rt);
+ blk=route_info_get_block(rt);
+ printf("segid 0x%lx nameid 0x%lx\n", st->segid, st->nameid);
+ street_name_get_by_id(&name, blk->mdata, st->nameid);
+ printf("'%s' '%s' %d\n", name.name1, name.name2, name.segment_count);
+ for (i = 0 ; i < name.segment_count ; i++) {
+ if (name.segments[i].segid == st->segid) {
+ printf("found: 0x%x, 0x%x\n", name.segments[i].country, name.segments[i].segid);
+ town_get_by_id(&town, co->map_data, name.segments[i].country, name.townassoc);
+ printf("%s/%s\n", town.name, town.district);
+ }
+ }
+ }
+#endif
+
+ window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ keyboard = build_keyboard(NULL, "/usr/local/share/gtkeyboard/DE.key");
+ vbox = gtk_vbox_new(FALSE, 0);
+ table = gtk_table_new(3, 8, FALSE);
+
+ entry_country = gtk_entry_new();
+ label_country = gtk_label_new("Land");
+ entry_postal = gtk_entry_new();
+ label_postal = gtk_label_new("PLZ");
+ entry_city = gtk_entry_new();
+ label_city = gtk_label_new("Ort");
+ entry_district = gtk_entry_new();
+ label_district = gtk_label_new("Ortsteil/Gemeinde");
+ hseparator1 = gtk_vseparator_new();
+ entry_street = gtk_entry_new();
+ label_street = gtk_label_new("Strasse");
+ entry_number = gtk_entry_new();
+ label_number = gtk_label_new("Nummer");
+ listbox = gtk_clist_new(9);
+ for (i=0 ; i < row_count ; i++) {
+ gtk_clist_append(GTK_CLIST(listbox), text);
+ }
+ gtk_clist_thaw(GTK_CLIST(listbox));
+ gtk_clist_columns_autosize (GTK_CLIST(listbox));
+
+ hseparator2 = gtk_vseparator_new();
+ button1 = gtk_button_new_with_label("Karte");
+ button2 = gtk_button_new_with_label("Ziel");
+
+ gtk_table_attach(GTK_TABLE(table), label_country, 0, 1, 0, 1, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), label_postal, 1, 2, 0, 1, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), label_city, 2, 3, 0, 1, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), entry_country, 0, 1, 1, 2, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_postal, 1, 2, 1, 2, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_city, 2, 3, 1, 2, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), label_district, 0, 1, 2, 3, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), label_street, 1, 2, 2, 3, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), label_number, 2, 3, 2, 3, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), entry_district, 0, 1, 3, 4, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_street, 1, 2, 3, 4, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), entry_number, 2, 3, 3, 4, 0, GTK_FILL|GTK_EXPAND, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), listbox, 0, 3, 4, 5, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+
+ gtk_table_attach(GTK_TABLE(table), button1, 0, 1, 5, 6, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+ gtk_table_attach(GTK_TABLE(table), button2, 2, 3, 5, 6, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
+
+ search->map_data=co->map_data;
+ search->clist=listbox;
+ gtk_signal_connect(GTK_OBJECT(entry_country), "changed", GTK_SIGNAL_FUNC(changed), search);
+ gtk_signal_connect(GTK_OBJECT(entry_postal), "changed", GTK_SIGNAL_FUNC(changed), search);
+ gtk_signal_connect(GTK_OBJECT(entry_city), "changed", GTK_SIGNAL_FUNC(changed), search);
+ gtk_signal_connect(GTK_OBJECT(entry_district), "changed", GTK_SIGNAL_FUNC(changed), search);
+ gtk_signal_connect(GTK_OBJECT(entry_street), "changed", GTK_SIGNAL_FUNC(changed), search);
+ gtk_signal_connect(GTK_OBJECT(entry_number), "changed", GTK_SIGNAL_FUNC(changed), search);
+ gtk_signal_connect(GTK_OBJECT(button1), "clicked", GTK_SIGNAL_FUNC(button_map), co);
+ gtk_signal_connect(GTK_OBJECT(button2), "clicked", GTK_SIGNAL_FUNC(button_destination), co);
+ gtk_widget_grab_focus(entry_city);
+
+ gtk_container_add(GTK_CONTAINER(vbox), table);
+ gtk_container_add(GTK_CONTAINER(vbox), keyboard);
+ gtk_container_add(GTK_CONTAINER(window2), vbox);
+ handlerid = gtk_timeout_add(256, (GtkFunction) track_focus, NULL);
+
+ gtk_signal_connect(GTK_OBJECT(listbox), "select-row", GTK_SIGNAL_FUNC(select_row), NULL);
+
+ gtk_widget_show_all(window2);
+
+ return 0;
+}