source: subversion/applications/utils/import/and2osm/2AND.c @ 4349

Last change on this file since 4349 was 4346, checked in by martinvoosterhout, 13 years ago

Move progress output to stderr.

File size: 11.9 KB
Line 
1/******************************************************************************
2 * $Id: AND2osm.c,v 1.0 2007/07/14 25:10:29 Marc Kessels $
3 * based on:
4 * $Id: shpdump.c,v 1.10 2002/04/10 16:59:29 warmerda Exp $
5 *
6 * Project:  AND2osm
7 * Purpose:  convert map-data provided by AND (www.and.com) to the
8 *           openstreetmap community (www.openstreetmap.org).
9 *           
10 * Author:   Frank Warmerdam, warmerdam@pobox.com
11 *           Marc Kessels, osm at kessels.name
12 ******************************************************************************
13 * Copyright (c) 1999, Frank Warmerdam
14 * Copyright (c) 2007, Marc Kessels
15 * Copyright (c) 2007  Jeroen Dekkers <jeroen@dekkers.cx>
16 *
17 * This software is available under the following "MIT Style" license,
18 * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This
19 * option is discussed in more detail in shapelib.html.
20 *
21 * --
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a
24 * copy of this software and associated documentation files (the "Software"),
25 * to deal in the Software without restriction, including without limitation
26 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
27 * and/or sell copies of the Software, and to permit persons to whom the
28 * Software is furnished to do so, subject to the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be included
31 * in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
34 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
36 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
38 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
39 * DEALINGS IN THE SOFTWARE.
40 ******************************************************************************
41 *
42 * $Log: shpdump.c,v $
43 * Revision 1.0 2007/07/14 15:14:00 Marc Kessels
44 * renamed to AND2osm.c
45 * added dbf input
46 * added osm output
47 *
48 * Revision 1.10  2002/04/10 16:59:29  warmerda
49 * added -validate switch
50 *
51 * Revision 1.9  2002/01/15 14:36:07  warmerda
52 * updated email address
53 *
54 * Revision 1.8  2000/07/07 13:39:45  warmerda
55 * removed unused variables, and added system include files
56 *
57 * Revision 1.7  1999/11/05 14:12:04  warmerda
58 * updated license terms
59 *
60 * Revision 1.6  1998/12/03 15:48:48  warmerda
61 * Added report of shapefile type, and total number of shapes.
62 *
63 * Revision 1.5  1998/11/09 20:57:36  warmerda
64 * use SHPObject.
65 *
66 * Revision 1.4  1995/10/21 03:14:49  warmerda
67 * Changed to use binary file access.
68 *
69 * Revision 1.3  1995/08/23  02:25:25  warmerda
70 * Added support for bounds.
71 *
72 * Revision 1.2  1995/08/04  03:18:11  warmerda
73 * Added header.
74 *
75 */
76
77//static char rcsid[] =
78//  "$Id: AND2osm.c,v 0.4 2007/07/29 11:04:00 Marc Kessels";
79
80//#include "shapefil.h"
81#include <stdlib.h>
82#include <stdio.h>
83#include <string.h>
84#include <unistd.h>
85#include <errno.h>
86#include "osm.h"
87#include "ways.h"
88#include "segments.h"
89#include "nodes.h"
90#include "tags.h"
91
92/* Control how often the display is update udring processing */
93#define DISPLAY_FREQUENCY   4096
94
95int postgres = 0;
96int osmChange = 0;
97
98static int use_boundingbox = 0;
99static double mybox_min[2],mybox_max[2];
100
101int testoverlap(SHPObject *psShape)
102{
103        double bbox_min[2],bbox_max[2];
104        long j;
105        if (!use_boundingbox)
106                return -1;
107
108        bbox_min[0]=psShape->dfXMin;
109        bbox_min[1]=psShape->dfYMin;
110        bbox_max[0]=psShape->dfXMax;
111        bbox_max[1]=psShape->dfYMax;
112
113
114        if (SHPCheckBoundsOverlap(bbox_min,bbox_max,mybox_min,mybox_max,2))
115        {
116                for ( j = 0; j < psShape->nVertices; j++ )
117                {
118                        if (      (psShape->padfY[j]<mybox_max[1])
119                                &&(psShape->padfY[j]>mybox_min[1])
120                                &&(psShape->padfX[j]<mybox_max[0])
121                                &&(psShape->padfX[j]>mybox_min[0]))
122                        return -1;
123                }
124        }
125        return 0;
126}
127
128int readfile(char * inputfile)
129{
130    SHPHandle   hSHP;
131    DBFHandle   hDBF;
132    int fileType;
133    int         nShapeType, nEntities;
134    long        i;
135    char        szTitle[12];
136    double      adfMinBound[4], adfMaxBound[4];
137
138
139/* -------------------------------------------------------------------- */
140/*      Open the passed shapefile.                                      */
141/* -------------------------------------------------------------------- */
142    hSHP = SHPOpen( inputfile, "rb" );
143        fprintf(stderr, "%s\n",inputfile);
144    if( hSHP == NULL )
145    {
146        fprintf(stderr,  "Unable to open: %s\n", inputfile );
147        return(1);
148    }
149
150
151    hDBF = DBFOpen( inputfile, "rb" );
152    if( hDBF == NULL )
153    {
154        fprintf(stderr,  "DBFOpen(%s,\"r\") failed.\n", inputfile );
155        return(2);
156    }
157   
158    /* -------------------------------------------------------------------- */
159    /*      Print out the file bounds.                                      */
160    /* -------------------------------------------------------------------- */
161    SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound );
162
163    fprintf(stderr,  "Shapefile Type: %s   # of Shapes: %d\n",
164            SHPTypeName( nShapeType ), nEntities );
165   
166    /*printf( "File Bounds: (%12.8f,%12.8f,%g,%g)\n"
167                    "         to  (%12.8f,%12.8f,%g,%g)\n",
168    adfMinBound[0],
169    adfMinBound[1],
170    adfMinBound[2],
171    adfMinBound[3],
172    adfMaxBound[0],
173    adfMaxBound[1],
174    adfMaxBound[2],
175    adfMaxBound[3] );*/
176
177
178/* -------------------------------------------------------------------- */
179/*        get file type                                                 */
180/* -------------------------------------------------------------------- */
181    DBFGetFieldInfo( hDBF, 0, szTitle, NULL, NULL );
182    if (strcmp(szTitle,"AREA")==0) fileType=NODE;
183    else if (strcmp(szTitle,"FNODE_")==0) fileType=ROAD;
184    else
185    {
186            fprintf(stderr,"filetype unkown! %s\n",inputfile);
187            return -1;
188    }
189
190/* -------------------------------------------------------------------- */
191/*      Skim over the list of shapes, printing all the vertices.        */
192/* -------------------------------------------------------------------- */
193   
194    for( i = 0; i <nEntities; i++ )
195    //i=11951;
196    {
197        long            j,iPart;
198        SHPObject       *psShape;
199        struct nodes *prevNode,*lastNode,*firstNode;
200        struct segments *lastSegment;
201        struct ways * way=NULL;
202
203        psShape = SHPReadObject( hSHP, i );
204        if ((i%DISPLAY_FREQUENCY)==0)
205        {
206            fprintf(stderr, "\r%7li/%7i   %7i/%7i                       ",i,nEntities,0,psShape->nVertices);
207        }
208        //printf("\n*******************************\n");
209       
210
211
212
213//for bounding box:
214/*      printf( "\nShape:%d (%s)  nVertices=%d, nParts=%d\n"
215                "  Bounds:(%12.3f,%12.3f, %g, %g)\n"
216                "      to (%12.3f,%12.3f, %g, %g)\n",
217                i, SHPTypeName(psShape->nSHPType),
218                psShape->nVertices, psShape->nParts,
219                psShape->dfXMin, psShape->dfYMin,
220                psShape->dfZMin, psShape->dfMMin,
221                psShape->dfXMax, psShape->dfYMax,
222                psShape->dfZMax, psShape->dfMMax );
223*/
224       
225        if (testoverlap(psShape))
226        {
227/*
228                if (fileType==ROAD)
229                        printf("\n%i,name=%s ",i,DBFReadStringAttribute( hDBF, i, 15 ) );
230                else
231                        printf("\n%i,name=%s ",i,DBFReadStringAttribute( hDBF, i, 11 ) );
232*/
233                //printf("%i\n",psShape->nVertices);
234                if (psShape->nVertices>1)
235                {
236                        if (psShape->nSHPType==SHPT_POLYGON) way=newWay(AREA); else way=newWay(ROAD);
237                };
238                prevNode=lastNode=firstNode=NULL;
239                for( j = 0, iPart=1; j < psShape->nVertices; j++ )
240                {
241                        if ((j>0)&&((j%DISPLAY_FREQUENCY)==0))
242                        {
243                                fprintf(stderr, "\r%7li/%7i   %7li/%7i                   ",i,nEntities,j,psShape->nVertices);
244                        }
245                        //printf("%i/%i\n",j,psShape->nVertices);
246                        prevNode=lastNode;
247                        lastNode=addNode(psShape->padfY[j],psShape->padfX[j]);
248                        //printf("%p\n",lastNode);
249                        if (j==0)
250                        {
251                                firstNode=lastNode;
252                        }
253                        else
254                        {
255                                if( iPart < psShape->nParts
256                                        && psShape->panPartStart[iPart] == j )
257                                {
258                                        iPart++;
259                                        //printf("\rdividing\n");
260                                        if(fileType == ROAD)
261                                                printf("Multipart road??? (rec=%ld)\n", i);
262                                }
263                                else
264                                {
265                                        //    printf(" seg\n");
266                                        lastSegment=addSegment(prevNode,lastNode);
267                                        //  printf(" seg2way\n");
268                                        addSegment2Way(way,lastSegment);
269                                }
270                        }
271/*                          printf("%i [%12.8f,%12.8f]\n",iPart,psShape->padfX[j],psShape->padfY[j]);*/
272
273                }
274                //printf("\n");
275        /*      if (psShape->nSHPType==SHPT_POLYGON)
276                {
277                        if (lastNode!=firstNode)
278                        {
279                                lastSegment=newSegment(lastNode,firstNode);
280                                addSegment2Way(way,lastSegment);
281                        }
282                }
283        */
284                if (psShape->nVertices>1)
285                {
286                        way->tag=mkTagList(hDBF, i,fileType,way->tag,firstNode,lastNode);
287                }
288                else
289                {
290                        firstNode->tag=mkTagList(hDBF, i,fileType,firstNode->tag,firstNode,lastNode);
291
292                }
293        }
294        SHPDestroyObject( psShape );
295    }
296    fprintf(stderr, "\r%7i/%7i                                     \n",nEntities,nEntities);
297
298    SHPClose( hSHP );
299    DBFClose( hDBF );
300
301#ifdef USE_DBMALLOC
302    malloc_dump(2);
303#endif
304
305    return(0);
306
307}
308
309static void bbox_error(void)
310{
311        fprintf (stderr, "Invalid argument to -b: %s\n", optarg);
312        exit(1);
313}
314
315
316#define FILENAME "020"
317int main(int argc, char ** argv )
318{
319        int c;
320        int do_borders = 1;
321        char *s, *s1, *s2, *s3, *s4, *p;
322       
323
324        init_tags();
325        init_ways();
326        init_nodes();
327        init_segments();
328        while ((c = getopt (argc, argv, "b:np?C:c")) != -1)
329                switch (c)
330                {
331                case 'b':
332                        s = strdup(optarg);
333                        if (!s)
334                        {
335                                fprintf (stderr, "malloc failed\n");
336                                exit(1);
337                        }
338                        s1 = strtok(s, ",");
339                        s2 = strtok(NULL, ",");
340                        s3 = strtok(NULL, ",");
341                        s4 = strtok(NULL, ",");
342
343                        if (s4 == NULL)
344                                bbox_error();
345
346                        mybox_min[0] = strtod(s1, &p);
347                        if (p == s1)
348                                bbox_error();
349                        mybox_min[1] = strtod(s2, &p);
350                        if (p == s2)
351                                bbox_error();
352                        mybox_max[0] = strtod(s3, &p);
353                        if (p == s3)
354                                bbox_error();
355                        mybox_max[1] = strtod(s4, &p);
356                        if (p == s4)
357                                bbox_error();
358
359                        printf ("minlon: %f, minlat: %f, maxlon: %f, maxlat: %f\n",
360                                mybox_min[0], mybox_min[1], mybox_max[0], mybox_max[1]);
361                        use_boundingbox=1;
362                        break;
363                case 'n':
364                        do_borders = 0;
365                        break;
366                case 'p':
367                        postgres = 1;
368                        break;
369                case 'C':
370                        if( chdir( optarg ) < 0 )
371                        {
372                                fprintf(stderr, "Failed to change to directory '%s': %s\n", optarg, strerror(errno) );
373                                exit(1);
374                        }
375                        break;
376                case 'c':
377                        osmChange = 1;
378                        break;
379                case '?':
380                default:
381                        /* Getopt will print an error message for us. */
382                        fprintf( stderr, "Usage: 2AND [-C dir] [-b minlon,minlat,maxlon,maxlat] [-n] [-p]\n"
383                                         "   -C dir                           - Change to given directory before starting\n"
384                                         "   -b minlon,minlat,maxlon,maxlat   - Bounding box to extract\n"
385                                         "   -n                               - Do not extract borders\n"
386                                         "   -p                               - Output postgresql SQL files\n"
387                                         "   -c                               - Output osmChange format\n");
388                        exit(1);
389                }
390       
391        Err_ND_attached_to_way=0;
392        Err_more_NDIDs_per_node=0;
393        Err_oneway_way_reversed=0;     
394        Err_toID_without_ANDID=0;
395        Err_fromID_without_ANDID=0;
396
397        /*readfiles*/
398       
399        if (access( "and_nodes.shp", F_OK) == 0)
400                readfile( "and_nodes");
401        readfile(FILENAME "_nosr_p");
402        readfile(FILENAME "_nosr_r");
403        if (do_borders) 
404        {
405                readfile(FILENAME "_admin0");
406                readfile(FILENAME "_admin1");
407                readfile(FILENAME "_admin8");
408        }
409        readfile(FILENAME "_a");
410        readfile(FILENAME "_ce");
411        readfile(FILENAME "_c");
412        readfile(FILENAME "_f");
413        readfile(FILENAME "_gf");
414        readfile(FILENAME "_in");
415        readfile(FILENAME "_i");
416        if (do_borders)
417        {
418                readfile(FILENAME "_o");
419        }
420        readfile(FILENAME "_pk");
421        readfile(FILENAME "_r_p");
422        readfile(FILENAME "_r_r");
423        readfile(FILENAME "_w");
424        openOutput();
425        save();
426        closeOutput();
427        printf("\nErr_ND_attached_to_way=%li\n",Err_ND_attached_to_way);
428        printf("Err_more_NDIDs_per_node=%li\n",Err_more_NDIDs_per_node);
429        printf("err_oneway_way_reversed=%li\n",Err_oneway_way_reversed);
430        printf("way \"toID\" refers to not present AND ID=%li\n",Err_toID_without_ANDID);
431        printf("way \"fromID\" refers to not present AND ID=%li\n",Err_fromID_without_ANDID);
432        return 0;
433       
434}
Note: See TracBrowser for help on using the repository browser.