/[zanavi_public1]/navit/navit/map/shapefile/shapefile.c
ZANavi

Contents of /navit/navit/map/shapefile/shapefile.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Mon Feb 4 17:41:59 2013 UTC (11 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 20031 byte(s)
new map version, lots of fixes and experimental new features
1 zoff99 2 /**
2     * Navit, a modular navigation system.
3     * Copyright (C) 2005-2008 Navit Team
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * version 2 as published by the Free Software Foundation.
8     *
9     * This program is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with this program; if not, write to the
16     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     * Boston, MA 02110-1301, USA.
18     */
19    
20     #include <stdlib.h>
21     #include <glib.h>
22     #include <stdio.h>
23     #include <string.h>
24     #include <math.h>
25     #include "config.h"
26     #ifdef HAVE_UNISTD_H
27     #include <unistd.h>
28     #endif
29     #include "debug.h"
30     #include "plugin.h"
31     #include "projection.h"
32     #include "item.h"
33     #include "map.h"
34     #include "maptype.h"
35     #include "attr.h"
36     #include "transform.h"
37     #include "file.h"
38     #include "shapefil.h"
39    
40    
41     #define IS_ARC(x) ((x).nSHPType == SHPT_ARC || (x).nSHPType == SHPT_ARCZ || (x).nSHPType == SHPT_ARCM)
42     #define IS_POLYGON(x) ((x).nSHPType == SHPT_POLYGON || (x).nSHPType == SHPT_POLYGONZ || (x).nSHPType == SHPT_POLYGONM)
43    
44     struct map_priv {
45     int id;
46     char *filename;
47     char *charset;
48     SHPHandle hSHP;
49     DBFHandle hDBF;
50     int nShapeType, nEntities, nFields;
51     double adfMinBound[4], adfMaxBound[4];
52     struct longest_match *lm;
53     char *dbfmap_data;
54     struct coord offset;
55     enum projection pro;
56     int flags;
57     };
58    
59    
60     struct map_rect_priv {
61     struct map_selection *sel;
62     struct map_priv *m;
63     struct item item;
64     int idx;
65     int cidx,cidx_rewind;
66     int part,part_rewind;
67     int aidx;
68     enum attr_type anext;
69     SHPObject *psShape;
70     char *str;
71     char *line;
72     int attr_pos;
73     struct attr *attr;
74     };
75    
76     static void
77     map_destroy_shapefile(struct map_priv *m)
78     {
79     dbg(1,"map_destroy_shapefile\n");
80     g_free(m);
81     }
82    
83     static void
84     shapefile_coord_rewind(void *priv_data)
85     {
86     struct map_rect_priv *mr=priv_data;
87     mr->cidx=mr->cidx_rewind;
88     mr->part=mr->part_rewind;
89     }
90    
91     static void
92     shapefile_coord(struct map_rect_priv *mr, int idx, struct coord *c)
93     {
94     SHPObject *psShape=mr->psShape;
95     struct coord cs;
96     struct coord_geo g;
97    
98     if (!mr->m->pro) {
99     g.lng=psShape->padfX[idx]+mr->m->offset.x;
100     g.lat=psShape->padfY[idx]+mr->m->offset.y;
101     transform_from_geo(projection_mg, &g, c);
102     } else {
103     cs.x=psShape->padfX[idx]+mr->m->offset.x;
104     cs.y=psShape->padfY[idx]+mr->m->offset.y;
105     transform_from_to(&cs, mr->m->pro, c, projection_mg);
106     }
107     }
108    
109     static int
110     shapefile_coord_get(void *priv_data, struct coord *c, int count)
111     {
112     struct map_rect_priv *mr=priv_data;
113     int ret=0;
114     int idx;
115    
116     SHPObject *psShape=mr->psShape;
117     while (count) {
118     idx=mr->cidx;
119     if (idx >= psShape->nVertices)
120     break;
121     if (mr->part+1 < psShape->nParts && idx == psShape->panPartStart[mr->part+1]) {
122     if (IS_POLYGON(*psShape)) {
123     mr->part++;
124     shapefile_coord(mr, 0, c);
125     } else if (IS_ARC(*psShape)) {
126     break;
127     } else {
128     dbg_assert("Neither POLYGON or ARC and has parts" == NULL);
129     }
130     } else {
131     shapefile_coord(mr, idx, c);
132     mr->cidx++;
133     }
134     ret++;
135     c++;
136     count--;
137     }
138     return ret;
139     }
140    
141     static void
142     shapefile_attr_rewind(void *priv_data)
143     {
144     struct map_rect_priv *mr=priv_data;
145     mr->aidx=0;
146     mr->attr_pos=0;
147     if (mr->m->flags & 1)
148     mr->anext=attr_none;
149     else
150     mr->anext=attr_debug;
151     }
152    
153    
154     struct longest_match_list_item {
155     void *data;
156     int match_idx_count;
157     int *match_idx;
158     };
159    
160     struct longest_match_list {
161     GList *longest_match_list_items;
162     };
163    
164    
165     struct longest_match {
166     GHashTable *match_hash;
167     char *match_present;
168     int match_present_count;
169     GList *longest_match_lists;
170     int longest_match_list_count;
171     };
172    
173     static void
174     longest_match_add_match(struct longest_match *lm, struct longest_match_list_item *lmi, char *match)
175     {
176     int idx;
177     if (!(idx=(int)(long)g_hash_table_lookup(lm->match_hash, match))) {
178     idx=lm->match_present_count++;
179     lm->match_present=g_renew(char, lm->match_present, lm->match_present_count);
180     g_hash_table_insert(lm->match_hash, g_strdup(match), (gpointer)(long)idx);
181     }
182     lmi->match_idx=g_renew(int, lmi->match_idx, lmi->match_idx_count+1);
183     lmi->match_idx[lmi->match_idx_count++]=idx;
184     }
185    
186     static void
187     longest_match_item_destroy(struct longest_match_list_item *lmi, long flags)
188     {
189     if (!lmi)
190     return;
191     if (flags & 2) {
192     g_free(lmi->data);
193     }
194     g_free(lmi->match_idx);
195     g_free(lmi);
196     }
197    
198     static struct longest_match_list_item *
199     longest_match_item_new(struct longest_match_list *lml, void *data)
200     {
201     struct longest_match_list_item *ret=g_new0(struct longest_match_list_item,1);
202     lml->longest_match_list_items=g_list_append(lml->longest_match_list_items, ret);
203     ret->data=data;
204    
205     return ret;
206     }
207    
208     static struct longest_match_list *
209     longest_match_list_new(struct longest_match *lm)
210     {
211     struct longest_match_list *ret=g_new0(struct longest_match_list,1);
212     lm->longest_match_lists=g_list_append(lm->longest_match_lists, ret);
213     return ret;
214     }
215    
216     static void
217     longest_match_list_destroy(struct longest_match_list *lml, long flags)
218     {
219     if (!lml)
220     return;
221     if (flags & 1) {
222     g_list_foreach(lml->longest_match_list_items, (GFunc)longest_match_item_destroy, (gpointer)flags);
223     g_list_free(lml->longest_match_list_items);
224     }
225     g_free(lml);
226     }
227    
228     static struct longest_match_list *
229     longest_match_get_list(struct longest_match *lm, int list)
230     {
231     GList *l=lm->longest_match_lists;
232     while (l && list > 0) {
233     l=g_list_next(l);
234     list++;
235     }
236     if (l)
237     return l->data;
238     return NULL;
239     }
240    
241     static struct longest_match *
242     longest_match_new(void)
243     {
244     struct longest_match *ret=g_new0(struct longest_match,1);
245 zoff99 31 ret->match_hash=g_hash_table_new_full(g_str_hash, g_str_equal, g_free_func, NULL);
246 zoff99 2 ret->match_present_count=1;
247     return ret;
248     }
249    
250     static void
251     longest_match_destroy(struct longest_match *lm, long flags)
252     {
253     if (!lm)
254     return;
255     if (flags & 1) {
256     g_list_foreach(lm->longest_match_lists, (GFunc)longest_match_list_destroy, (gpointer)flags);
257     g_list_free(lm->longest_match_lists);
258     }
259     g_hash_table_destroy(lm->match_hash);
260     g_free(lm->match_present);
261     g_free(lm);
262     }
263    
264     static void
265     longest_match_clear(struct longest_match *lm)
266     {
267     if (lm->match_present)
268     memset(lm->match_present, 0, lm->match_present_count);
269     }
270    
271     static void
272     longest_match_add_key_value(struct longest_match *lm, char *k, char *v)
273     {
274     char* buffer=g_alloca(strlen(k)+strlen(v)+2);
275     int idx;
276    
277     strcpy(buffer,"*=*");
278     if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer)))
279     lm->match_present[idx]=1;
280    
281     sprintf(buffer,"%s=*", k);
282     if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer)))
283     lm->match_present[idx]=2;
284    
285     sprintf(buffer,"*=%s", v);
286     if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer)))
287     lm->match_present[idx]=2;
288    
289     sprintf(buffer,"%s=%s", k, v);
290     if ((idx=(int)(long)g_hash_table_lookup(lm->match_hash, buffer)))
291     lm->match_present[idx]=4;
292     }
293    
294     static int
295     longest_match_list_find(struct longest_match *lm, struct longest_match_list *lml, void **list, int max_list_len)
296     {
297     int j,longest=0,ret=0,sum,val;
298     struct longest_match_list_item *curr;
299     GList *l=lml->longest_match_list_items;
300    
301    
302     while (l) {
303     sum=0;
304     curr=l->data;
305     for (j = 0 ; j < curr->match_idx_count ; j++) {
306     val=lm->match_present[curr->match_idx[j]];
307     if (val)
308     sum+=val;
309     else {
310     sum=-1;
311     break;
312     }
313     }
314     if (sum > longest) {
315     longest=sum;
316     ret=0;
317     }
318     if (sum > 0 && sum == longest && ret < max_list_len)
319     list[ret++]=curr->data;
320     l=g_list_next(l);
321     }
322     return ret;
323     }
324    
325    
326     static void
327     build_match(struct longest_match *lm, struct longest_match_list *lml, char *line)
328     {
329     struct longest_match_list_item *lmli;
330     char *kvl=NULL,*i=NULL,*p,*kv;
331     dbg(1,"line=%s\n",line);
332     kvl=line;
333     p=strchr(line,'\t');
334     if (p) {
335     while (*p == '\t')
336     *p++='\0';
337     i=p;
338     }
339     lmli=longest_match_item_new(lml,g_strdup(i));
340     while ((kv=strtok(kvl, ","))) {
341     kvl=NULL;
342     longest_match_add_match(lm, lmli, kv);
343     }
344     }
345    
346     static void
347     build_matches(struct map_priv *m,char *matches)
348     {
349     char *matches2=g_strdup(matches);
350     char *l=matches2,*p;
351     struct longest_match_list *lml;
352    
353     m->lm=longest_match_new();
354     lml=longest_match_list_new(m->lm);
355     while (l) {
356     p=strchr(l,'\n');
357     if (p)
358     *p++='\0';
359     if (strlen(l))
360     build_match(m->lm,lml,l);
361     l=p;
362     }
363     g_free(matches2);
364     }
365    
366     static void
367     process_fields(struct map_priv *m, int id)
368     {
369     int i;
370     char szTitle[12],*pszTypeName,*str;
371     int nWidth, nDecimals;
372    
373     for (i = 0 ; i < m->nFields ; i++) {
374    
375     switch (DBFGetFieldInfo(m->hDBF, i, szTitle, &nWidth, &nDecimals )) {
376     case FTString:
377     pszTypeName = "String";
378     str=g_strdup(DBFReadStringAttribute( m->hDBF, id, i ));
379     break;
380     case FTInteger:
381     pszTypeName = "Integer";
382     str=g_strdup_printf("%d",DBFReadIntegerAttribute( m->hDBF, id, i ));
383     break;
384     case FTDouble:
385     pszTypeName = "Double";
386     str=g_strdup_printf("%lf",DBFReadDoubleAttribute( m->hDBF, id, i ));
387     break;
388     case FTInvalid:
389     pszTypeName = "Invalid";
390     str=NULL;
391     break;
392     default:
393     pszTypeName = "Unknown";
394     str=NULL;
395     }
396     longest_match_add_key_value(m->lm, szTitle, str);
397     }
398     }
399    
400     static int
401     attr_resolve(struct map_rect_priv *mr, enum attr_type attr_type, struct attr *attr)
402     {
403     char name[1024];
404     char value[1024];
405     char szTitle[12];
406     const char *str;
407     char *col,*type=NULL;
408     int i,len, nWidth, nDecimals;
409     if (!mr->line)
410     return 0;
411     if (attr_type != attr_any)
412     type=attr_to_name(attr_type);
413     if (attr_from_line(mr->line,type,&mr->attr_pos,value,name)) {
414     len=strlen(value);
415     if (value[0] == '$' && value[1] == '{' && value[len-1] == '}') {
416     int found=0;
417     value[len-1]='\0';
418     col=value+2;
419     for (i = 0 ; i < mr->m->nFields ; i++) {
420     if (DBFGetFieldInfo(mr->m->hDBF, i, szTitle, &nWidth, &nDecimals ) == FTString && !strcmp(szTitle,col)) {
421     str=DBFReadStringAttribute( mr->m->hDBF, mr->item.id_hi, i);
422     strcpy(value,str);
423     found=1;
424     break;
425     }
426     }
427     if (!found)
428     value[0]='\0';
429     }
430     if (!value[0])
431     return -1;
432     dbg(1,"name=%s value=%s\n",name,value);
433     attr_free(mr->attr);
434     mr->attr=attr_new_from_text(name,value);
435     if (mr->attr) {
436     *attr=*mr->attr;
437     return 1;
438     }
439     return -1;
440     }
441     return 0;
442     }
443    
444     static int
445     shapefile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
446     {
447     struct map_rect_priv *mr=priv_data;
448     struct map_priv *m=mr->m;
449     char szTitle[12],*pszTypeName, *str;
450     int code, ret, nWidth, nDecimals;
451    
452     attr->type=attr_type;
453     switch (attr_type) {
454     case attr_any:
455     while ((code=attr_resolve(mr, attr_type, attr))) {
456     if (code == 1)
457     return 1;
458     }
459     while (mr->anext != attr_none) {
460     ret=shapefile_attr_get(priv_data, mr->anext, attr);
461     if (ret)
462     return ret;
463     }
464     return 0;
465     case attr_debug:
466     if (mr->aidx >= m->nFields) {
467     mr->anext=attr_none;
468     return 0;
469     }
470     switch (DBFGetFieldInfo(m->hDBF, mr->aidx, szTitle, &nWidth, &nDecimals )) {
471     case FTString:
472     pszTypeName = "String";
473     str=g_strdup(DBFReadStringAttribute( m->hDBF, mr->item.id_hi, mr->aidx ));
474     break;
475     case FTInteger:
476     pszTypeName = "Integer";
477     str=g_strdup_printf("%d",DBFReadIntegerAttribute( m->hDBF, mr->item.id_hi, mr->aidx ));
478     break;
479     case FTDouble:
480     pszTypeName = "Double";
481     str=g_strdup_printf("%lf",DBFReadDoubleAttribute( m->hDBF, mr->item.id_hi, mr->aidx ));
482     break;
483     case FTInvalid:
484     pszTypeName = "Invalid";
485     str=NULL;
486     break;
487     default:
488     pszTypeName = "Unknown";
489     str=NULL;
490     }
491     g_free(mr->str);
492     mr->str=attr->u.str=g_strdup_printf("%s=%s(%s)",szTitle,str,pszTypeName);
493     g_free(str);
494     mr->aidx++;
495     return 1;
496     default:
497     return (attr_resolve(mr, attr_type, attr) == 1);
498     }
499     }
500    
501     static struct item_methods methods_shapefile = {
502     shapefile_coord_rewind,
503     shapefile_coord_get,
504     shapefile_attr_rewind,
505     shapefile_attr_get,
506     };
507    
508     static struct map_rect_priv *
509     map_rect_new_shapefile(struct map_priv *map, struct map_selection *sel)
510     {
511     struct map_rect_priv *mr;
512     char *dbfmapfile=g_strdup_printf("%s.dbfmap", map->filename);
513     void *data;
514     struct file *file;
515     int size;
516     int changed=0;
517     if ((file=file_create(dbfmapfile, 0))) {
518     size=file_size(file);
519     data=file_data_read_all(file);
520     if (data) {
521     if (!map->dbfmap_data || size != strlen(map->dbfmap_data) || strncmp(data,map->dbfmap_data,size)) {
522     g_free(map->dbfmap_data);
523     map->dbfmap_data=g_malloc(size+1);
524     memcpy(map->dbfmap_data, data, size);
525     map->dbfmap_data[size]='\0';
526     changed=1;
527     }
528     file_data_free(file, data);
529     }
530     file_destroy(file);
531     } else {
532     dbg(0,"Failed to open %s\n",dbfmapfile);
533     if (map->dbfmap_data) {
534     changed=1;
535     g_free(map->dbfmap_data);
536     map->dbfmap_data=NULL;
537     }
538     }
539     dbg(1,"%s changed %d old %p\n",dbfmapfile,changed,map->dbfmap_data);
540     if (changed) {
541     longest_match_destroy(map->lm,1);
542     map->lm=NULL;
543     if (map->dbfmap_data) {
544     build_matches(map,map->dbfmap_data);
545     }
546     }
547     dbg(1,"map_rect_new_shapefile\n");
548     mr=g_new0(struct map_rect_priv, 1);
549     mr->m=map;
550     mr->idx=0;
551     mr->item.id_lo=0;
552     mr->item.id_hi=0;
553     mr->item.meth=&methods_shapefile;
554     mr->item.priv_data=mr;
555     g_free(dbfmapfile);
556     return mr;
557     }
558    
559    
560     static void
561     map_rect_destroy_shapefile(struct map_rect_priv *mr)
562     {
563     if (mr->psShape)
564     SHPDestroyObject(mr->psShape);
565     attr_free(mr->attr);
566     g_free(mr->str);
567     g_free(mr);
568     }
569    
570     static struct item *
571     map_rect_get_item_shapefile(struct map_rect_priv *mr)
572     {
573     struct map_priv *m=mr->m;
574     void *lines[5];
575     struct longest_match_list *lml;
576     int count;
577     char type[1024];
578    
579     if (mr->psShape && IS_ARC(*mr->psShape) && mr->part+1 < mr->psShape->nParts) {
580     mr->part++;
581     mr->part_rewind=mr->part;
582     mr->cidx_rewind=mr->psShape->panPartStart[mr->part];
583     } else {
584     if (mr->idx >= m->nEntities)
585     return NULL;
586     mr->item.id_hi=mr->idx;
587     if (mr->psShape)
588     SHPDestroyObject(mr->psShape);
589     mr->psShape=SHPReadObject(m->hSHP, mr->idx);
590     if (mr->psShape->nVertices > 1)
591     mr->item.type=type_street_unkn;
592     else
593     mr->item.type=type_point_unkn;
594     if (m->lm) {
595     longest_match_clear(m->lm);
596     process_fields(m, mr->idx);
597    
598     lml=longest_match_get_list(m->lm, 0);
599     count=longest_match_list_find(m->lm, lml, lines, sizeof(lines)/sizeof(void *));
600     if (count) {
601     mr->line=lines[0];
602     if (attr_from_line(mr->line,"type",NULL,type,NULL)) {
603     dbg(1,"type='%s'\n", type);
604     mr->item.type=item_from_name(type);
605     if (mr->item.type == type_none && strcmp(type,"none"))
606     dbg(0,"Warning: type '%s' unknown\n", type);
607     } else {
608     dbg(0,"failed to get attribute type\n");
609     }
610     } else
611     mr->line=NULL;
612     }
613     mr->idx++;
614     mr->part_rewind=0;
615     mr->cidx_rewind=0;
616     }
617     shapefile_coord_rewind(mr);
618     shapefile_attr_rewind(mr);
619     return &mr->item;
620     }
621    
622     static struct item *
623     map_rect_get_item_byid_shapefile(struct map_rect_priv *mr, int id_hi, int id_lo)
624     {
625     mr->idx=id_hi;
626     while (id_lo--) {
627     if (!map_rect_get_item_shapefile(mr))
628     return NULL;
629     }
630     return map_rect_get_item_shapefile(mr);
631     }
632    
633     static struct map_methods map_methods_shapefile = {
634     projection_mg,
635     "iso8859-1",
636     map_destroy_shapefile,
637     map_rect_new_shapefile,
638     map_rect_destroy_shapefile,
639     map_rect_get_item_shapefile,
640     map_rect_get_item_byid_shapefile,
641     };
642    
643     static struct map_priv *
644     map_new_shapefile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
645     {
646     struct map_priv *m;
647     struct attr *data=attr_search(attrs, NULL, attr_data);
648     struct attr *charset=attr_search(attrs, NULL, attr_charset);
649     struct attr *projectionname=attr_search(attrs, NULL, attr_projectionname);
650     struct attr *flags=attr_search(attrs, NULL, attr_flags);
651     struct file_wordexp *wexp;
652     char *wdata;
653     char **wexp_data;
654     char *shapefile,*dbffile;
655     if (! data)
656     return NULL;
657     dbg(1,"map_new_shapefile %s\n", data->u.str);
658     wdata=g_strdup(data->u.str);
659     wexp=file_wordexp_new(wdata);
660     wexp_data=file_wordexp_get_array(wexp);
661     *meth=map_methods_shapefile;
662    
663     m=g_new0(struct map_priv, 1);
664     m->filename=g_strdup(wexp_data[0]);
665     shapefile=g_strdup_printf("%s.shp", m->filename);
666     m->hSHP=SHPOpen(shapefile, "rb" );
667     SHPGetInfo( m->hSHP, &m->nEntities, &m->nShapeType, m->adfMinBound, m->adfMaxBound );
668     g_free(shapefile);
669     dbffile=g_strdup_printf("%s.dbf", m->filename);
670     m->hDBF=DBFOpen(dbffile, "rb");
671     m->nFields=DBFGetFieldCount(m->hDBF);
672     g_free(dbffile);
673     dbg(1,"map_new_shapefile %s %s\n", m->filename, wdata);
674     if (charset) {
675     m->charset=g_strdup(charset->u.str);
676     meth->charset=m->charset;
677     }
678     if (projectionname)
679     m->pro=projection_from_name(projectionname->u.str, &m->offset);
680     if (flags)
681     m->flags=flags->u.num;
682     file_wordexp_destroy(wexp);
683     return m;
684     }
685    
686     void
687     plugin_init(void)
688     {
689     dbg(1,"shapefile: plugin_init\n");
690     plugin_register_map_type("shapefile", map_new_shapefile);
691     }
692    
693     /************************************************************************/
694     /* VSI_SHP_Open() */
695     /************************************************************************/
696    
697     static SAFile VSI_SHP_Open( const char *pszFilename, const char *pszAccess )
698    
699     {
700     return (SAFile)fopen(pszFilename, pszAccess);
701     }
702    
703     /************************************************************************/
704     /* VSI_SHP_Read() */
705     /************************************************************************/
706    
707     static SAOffset VSI_SHP_Read( void *p, SAOffset size, SAOffset nmemb, SAFile file )
708    
709     {
710     return fread(p, size, nmemb, (FILE *)file);
711     }
712    
713     /************************************************************************/
714     /* VSI_SHP_Write() */
715     /************************************************************************/
716    
717     static SAOffset VSI_SHP_Write( void *p, SAOffset size, SAOffset nmemb, SAFile file )
718    
719     {
720     return fwrite(p, size, nmemb, (FILE *)file);
721     }
722    
723     /************************************************************************/
724     /* VSI_SHP_Seek() */
725     /************************************************************************/
726    
727     static SAOffset VSI_SHP_Seek( SAFile file, SAOffset offset, int whence )
728    
729     {
730     return fseek((FILE *)file, offset, whence);
731     }
732    
733     /************************************************************************/
734     /* VSI_SHP_Tell() */
735     /************************************************************************/
736    
737     static SAOffset VSI_SHP_Tell( SAFile file )
738    
739     {
740     return ftell((FILE *)file);
741     }
742    
743    
744     static int VSI_SHP_Flush( SAFile file )
745    
746     {
747     return fflush((FILE *)file);
748     }
749    
750     /************************************************************************/
751     /* VSI_SHP_Close() */
752     /************************************************************************/
753    
754     static int VSI_SHP_Close( SAFile file )
755    
756     {
757     return fclose((FILE *)file);
758     }
759    
760     /************************************************************************/
761     /* SADError() */
762     /************************************************************************/
763    
764     static void VSI_SHP_Error( const char *message )
765    
766     {
767     dbg(0,"error:%s\n", message);
768     }
769    
770     /************************************************************************/
771     /* VSI_SHP_Remove() */
772     /************************************************************************/
773    
774     static int VSI_SHP_Remove( const char *pszFilename )
775    
776     {
777     return unlink(pszFilename);
778     }
779    
780     /************************************************************************/
781     /* SASetupDefaultHooks() */
782     /************************************************************************/
783    
784     void SASetupDefaultHooks( SAHooks *psHooks )
785    
786     {
787     psHooks->FOpen = VSI_SHP_Open;
788     psHooks->FRead = VSI_SHP_Read;
789     psHooks->FWrite = VSI_SHP_Write;
790     psHooks->FSeek = VSI_SHP_Seek;
791     psHooks->FTell = VSI_SHP_Tell;
792     psHooks->FFlush = VSI_SHP_Flush;
793     psHooks->FClose = VSI_SHP_Close;
794    
795     psHooks->Remove = VSI_SHP_Remove;
796     psHooks->Atof = atof;
797    
798     psHooks->Error = VSI_SHP_Error;
799     }
800    
801    

   
Visit the ZANavi Wiki