source: subversion/applications/utils/export/osm2pgsql/osm2pgsql.c @ 29369

Last change on this file since 29369 was 29265, checked in by apmon, 7 years ago

[osm2pgsql] make use of printf and fprintf(stderr a bit more consistent

  • Property svn:keywords set to Rev
File size: 29.5 KB
Line 
1/*
2#-----------------------------------------------------------------------------
3# osm2pgsql - converts planet.osm file into PostgreSQL
4# compatible output suitable to be rendered by mapnik
5# Use: osm2pgsql planet.osm.bz2
6#-----------------------------------------------------------------------------
7# Original Python implementation by Artem Pavlenko
8# Re-implementation by Jon Burgess, Copyright 2006
9#
10# This program is free software; you can redistribute it and/or
11# modify it under the terms of the GNU General Public License
12# as published by the Free Software Foundation; either version 2
13# of the License, or (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23#-----------------------------------------------------------------------------
24*/
25
26#include "config.h"
27
28#include <stdio.h>
29#include <unistd.h>
30#include <stdlib.h>
31#include <string.h>
32#include <assert.h>
33#include <getopt.h>
34#include <libgen.h>
35#include <time.h>
36
37#include <libpq-fe.h>
38
39#include <libxml/xmlstring.h>
40#include <libxml/xmlreader.h>
41
42#include "osmtypes.h"
43#include "build_geometry.h"
44#include "middle-pgsql.h"
45#include "middle-ram.h"
46#include "node-ram-cache.h"
47#include "output-pgsql.h"
48#include "output-gazetteer.h"
49#include "output-null.h"
50#include "sanitizer.h"
51#include "reprojection.h"
52#include "text-tree.h"
53#include "input.h"
54#include "sprompt.h"
55#include "parse-xml2.h"
56#include "parse-primitive.h"
57#include "parse-o5m.h"
58
59#ifdef BUILD_READER_PBF
60#  include "parse-pbf.h"
61#endif
62
63#define INIT_MAX_MEMBERS 64
64#define INIT_MAX_NODES  4096
65
66int verbose;
67
68/* Data structure carrying all parsing related variables */
69static struct osmdata_t osmdata = { 
70  .filetype = FILETYPE_NONE,
71  .action   = ACTION_NONE,
72  .bbox     = NULL
73};
74
75
76static int parse_bbox(struct osmdata_t *osmdata)
77{
78    int n;
79
80    if (!osmdata->bbox)
81        return 0;
82
83    n = sscanf(osmdata->bbox, "%lf,%lf,%lf,%lf", &(osmdata->minlon), &(osmdata->minlat), &(osmdata->maxlon), &(osmdata->maxlat));
84    if (n != 4) {
85        fprintf(stderr, "Bounding box must be specified like: minlon,minlat,maxlon,maxlat\n");
86        return 1;
87    }
88    if (osmdata->maxlon <= osmdata->minlon) {
89        fprintf(stderr, "Bounding box failed due to maxlon <= minlon\n");
90        return 1;
91    }
92    if (osmdata->maxlat <= osmdata->minlat) {
93        fprintf(stderr, "Bounding box failed due to maxlat <= minlat\n");
94        return 1;
95    }
96    fprintf(stderr, "Applying Bounding box: %f,%f to %f,%f\n", osmdata->minlon, osmdata->minlat, osmdata->maxlon, osmdata->maxlat);
97    return 0;
98}
99
100
101
102void exit_nicely()
103{
104    fprintf(stderr, "Error occurred, cleaning up\n");
105    osmdata.out->cleanup();
106    exit(1);
107}
108 
109static void short_usage(char *arg0)
110{
111    const char *name = basename(arg0);
112
113    fprintf(stderr, "Usage error. For further information see:\n");
114    fprintf(stderr, "\t%s -h|--help\n", name);
115}
116
117static void long_usage(char *arg0)
118{
119    int i;
120    const char *name = basename(arg0);
121
122    printf("Usage:\n");
123    printf("\t%s [options] planet.osm\n", name);
124    printf("\t%s [options] planet.osm.{gz,bz2}\n", name);
125    printf("\t%s [options] file1.osm file2.osm file3.osm\n", name);
126    printf("\nThis will import the data from the OSM file(s) into a PostgreSQL database\n");
127    printf("suitable for use by the Mapnik renderer\n");
128    printf("\nOptions:\n");
129    printf("   -a|--append\t\tAdd the OSM file into the database without removing\n");
130    printf("              \t\texisting data.\n");
131    printf("   -b|--bbox\t\tApply a bounding box filter on the imported data\n");
132    printf("              \t\tMust be specified as: minlon,minlat,maxlon,maxlat\n");
133    printf("              \t\te.g. --bbox -0.5,51.25,0.5,51.75\n");
134    printf("   -c|--create\t\tRemove existing data from the database. This is the \n");
135    printf("              \t\tdefault if --append is not specified.\n");
136    printf("   -d|--database\tThe name of the PostgreSQL database to connect\n");
137    printf("              \t\tto (default: gis).\n");
138    printf("   -i|--tablespace-index\tThe name of the PostgreSQL tablespace where\n");
139    printf("              \t\tall indexes will be created.\n");
140    printf("              \t\tThe following options allow more fine-grained control:\n");
141    printf("      --tablespace-main-data \ttablespace for main tables\n");
142    printf("      --tablespace-main-index\ttablespace for main table indexes\n");
143    printf("      --tablespace-slim-data \ttablespace for slim mode tables\n");
144    printf("      --tablespace-slim-index\ttablespace for slim mode indexes\n");
145    printf("              \t\t(if unset, use db's default; -i is equivalent to setting\n");
146    printf("              \t\t--tablespace-main-index and --tablespace-slim-index)\n");
147    printf("   -l|--latlong\t\tStore data in degrees of latitude & longitude.\n");
148    printf("   -m|--merc\t\tStore data in proper spherical mercator (default)\n");
149    printf("   -M|--oldmerc\t\tStore data in the legacy OSM mercator format\n");
150    printf("   -E|--proj num\tUse projection EPSG:num\n");
151    printf("   -u|--utf8-sanitize\tRepair bad UTF8 input data (present in planet\n");
152    printf("                \tdumps prior to August 2007). Adds about 10%% overhead.\n");
153    printf("   -p|--prefix\t\tPrefix for table names (default planet_osm)\n");
154    printf("   -s|--slim\t\tStore temporary data in the database. This greatly\n");
155    printf("            \t\treduces the RAM usage but is much slower. This switch is\n");
156    printf("            \t\trequired if you want to update with --append later.\n");
157
158    if (sizeof(int*) == 4) {
159        printf("            \t\tThis program was compiled on a 32bit system, so at most\n");
160        printf("            \t\t3GB of RAM will be used. If you encounter problems\n");
161        printf("            \t\tduring import, you should try this switch.\n");
162    }
163    printf("      --drop\t\tonly with --slim: drop temporary tables after import (no updates).\n");
164   
165    printf("   -S|--style\t\tLocation of the style file. Defaults to " OSM2PGSQL_DATADIR "/default.style\n");
166    printf("   -C|--cache\t\tNow required for slim and non-slim modes: \n");
167    printf("             \t\tUse up to this many MB for caching nodes (default: 800)\n");
168    printf("   -U|--username\tPostgresql user name\n");
169    printf("             \t\tpassword can be given by prompt or PGPASS environment variable.\n");
170    printf("   -W|--password\tForce password prompt.\n");
171    printf("   -H|--host\t\tDatabase server hostname or socket location.\n");
172    printf("   -P|--port\t\tDatabase server port.\n");
173    printf("   -e|--expire-tiles [min_zoom-]max_zoom\tCreate a tile expiry list.\n");
174    printf("   -o|--expire-output filename\tOutput filename for expired tiles list.\n");
175    printf("   -r|--input-reader\tInput frontend.\n");
176    printf("              \t\tlibxml2   - Parse XML using libxml2. (default)\n");
177    printf("              \t\tprimitive - Primitive XML parsing.\n");
178#ifdef BUILD_READER_PBF
179    printf("              \t\tpbf       - OSM binary format.\n");
180#endif
181    printf("   -O|--output\t\tOutput backend.\n");
182    printf("              \t\tpgsql - Output to a PostGIS database. (default)\n");
183    printf("              \t\tgazetteer - Output to a PostGIS database suitable for gazetteer\n");
184    printf("              \t\tnull  - No output. Useful for testing.\n");
185    printf("   -x|--extra-attributes\n");
186    printf("              \t\tInclude attributes for each object in the database.\n");
187    printf("              \t\tThis includes the username, userid, timestamp and version.\n"); 
188    printf("              \t\tNote: this option also requires additional entries in your style file.\n"); 
189    printf("   -k|--hstore\t\tAdd tags without column to an additional hstore (key/value) column to postgresql tables\n");
190    printf("      --hstore-match-only\tOnly keep objects that have a value in one of the columns\n");
191    printf("      -                  \t(normal action with --hstore is to keep all objects)\n");
192    printf("   -j|--hstore-all\tAdd all tags to an additional hstore (key/value) column in postgresql tables\n");
193    printf("   -z|--hstore-column\tAdd an additional hstore (key/value) column containing all tags\n");
194    printf("                     \tthat start with the specified string, eg --hstore-column \"name:\" will\n");
195    printf("                     \tproduce an extra hstore column that contains all name:xx tags\n");
196    printf("      --hstore-add-index\tAdd index to hstore column.\n");
197    printf("   -G|--multi-geometry\tGenerate multi-geometry features in postgresql tables.\n");
198    printf("   -K|--keep-coastlines\tKeep coastline data rather than filtering it out.\n");
199    printf("              \t\tBy default natural=coastline tagged data will be discarded based on the\n");
200    printf("              \t\tassumption that post-processed Coastline Checker shapefiles will be used.\n");
201    printf("      --exclude-invalid-polygon\n");
202#ifdef HAVE_FORK
203    printf("      --number-processes\t\tSpecifies the number of parallel processes used for certain operations\n");
204    printf("             \t\tDefault is 1\n");
205#endif
206    printf("   -I|--disable-parallel-indexing\tDisable indexing all tables concurrently.\n");
207    printf("      --unlogged\tUse unlogged tables (lost on crash but faster). Requires PostgreSQL 9.1.\n");
208    printf("      --cache-strategy\tSpecifies the method used to cache nodes in ram.\n");
209    printf("                      \t\tAvailable options are:\n");
210    printf("                      \t\tdense: caching strategy optimised for full planet import\n");
211    printf("                      \t\tchunked: caching strategy optimised for non-contigouse memory allocation\n");
212    printf("                      \t\tsparse: caching strategy optimised for small extracts\n");
213    printf("                      \t\toptimized: automatically combines dense and sparse strategies for optimal storage efficiency.\n");
214    printf("                      \t\t           optimized may use twice as much virtual memory, but no more physical memory\n");
215
216#ifdef __amd64__
217    printf("                      \t\t   The default is \"optimized\"\n");
218#else
219    /* use "chunked" as a default in 32 bit compilations, as it is less wasteful of virtual memory than "optimized"*/
220    printf("                      \t\t   The default is \"sparse\"\n");
221#endif
222    printf("      --flat-nodes\tSpecifies the flat file to use to persistently store node information in slim mode instead of in pgsql\n");
223    printf("                  \t\tThis file is a single > 16Gb large file. This method is only recomended for full planet imports\n");
224    printf("                   \t\tas it doesn't work well with small extracts. The default is disabled\n");
225    printf("   -h|--help\t\tHelp information.\n");
226    printf("   -v|--verbose\t\tVerbose output.\n");
227    printf("\n");
228    if(!verbose)
229    {
230        printf("Add -v to display supported projections.\n");
231        printf("Use -E to access any espg projections (usually in /usr/share/proj/epsg)\n" );
232    }
233    else
234    {
235        printf("Supported projections:\n" );
236        for(i=0; i<PROJ_COUNT; i++ )
237        {
238            printf( "%-20s(%2s) SRS:%6d %s\n", 
239                    Projection_Info[i].descr, Projection_Info[i].option, Projection_Info[i].srs, Projection_Info[i].proj4text);
240        }
241    }
242}
243
244const char *build_conninfo(const char *db, const char *username, const char *password, const char *host, const char *port)
245{
246    static char conninfo[1024];
247
248    conninfo[0]='\0';
249    strcat(conninfo, "dbname='");
250    strcat(conninfo, db);
251    strcat(conninfo, "'");
252
253    if (username) {
254        strcat(conninfo, " user='");
255        strcat(conninfo, username);
256        strcat(conninfo, "'");
257    }
258    if (password) {
259        strcat(conninfo, " password='");
260        strcat(conninfo, password);
261        strcat(conninfo, "'");
262    }
263    if (host) {
264        strcat(conninfo, " host='");
265        strcat(conninfo, host);
266        strcat(conninfo, "'");
267    }
268    if (port) {
269        strcat(conninfo, " port='");
270        strcat(conninfo, port);
271        strcat(conninfo, "'");
272    }
273
274    return conninfo;
275}
276
277void realloc_nodes(struct osmdata_t *osmdata)
278{
279  if( osmdata->nd_max == 0 )
280    osmdata->nd_max = INIT_MAX_NODES;
281  else
282    osmdata->nd_max <<= 1;
283   
284  osmdata->nds = realloc( osmdata->nds, osmdata->nd_max * sizeof( osmdata->nds[0] ) );
285  if( !osmdata->nds )
286  {
287    fprintf( stderr, "Failed to expand node list to %d\n", osmdata->nd_max );
288    exit_nicely();
289  }
290}
291
292void realloc_members(struct osmdata_t *osmdata)
293{
294  if( osmdata->member_max == 0 )
295    osmdata->member_max = INIT_MAX_NODES;
296  else
297    osmdata->member_max <<= 1;
298   
299  osmdata->members = realloc( osmdata->members, osmdata->member_max * sizeof( osmdata->members[0] ) );
300  if( !osmdata->members )
301  {
302    fprintf( stderr, "Failed to expand member list to %d\n", osmdata->member_max );
303    exit_nicely();
304  }
305}
306
307void resetMembers(struct osmdata_t *osmdata)
308{
309  unsigned i;
310  for(i = 0; i < osmdata->member_count; i++ )
311    free( osmdata->members[i].role );
312}
313
314void printStatus(struct osmdata_t *osmdata)
315{
316    time_t now;
317    time_t end_nodes;
318    time_t end_way;
319    time_t end_rel;
320    time(&now);
321    end_nodes = osmdata->start_way > 0 ? osmdata->start_way : now;
322    end_way = osmdata->start_rel > 0 ? osmdata->start_rel : now;
323    end_rel =  now;
324    fprintf(stderr, "\rProcessing: Node(%" PRIdOSMID "k %.1fk/s) Way(%" PRIdOSMID "k %.2fk/s) Relation(%" PRIdOSMID " %.2f/s)",
325            osmdata->count_node/1000,
326            (double)osmdata->count_node/1000.0/((int)(end_nodes - osmdata->start_node) > 0 ? (double)(end_nodes - osmdata->start_node) : 1.0),
327            osmdata->count_way/1000,
328            osmdata->count_way > 0 ? (double)osmdata->count_way/1000.0/
329            ((double)(end_way - osmdata->start_way) > 0.0 ? (double)(end_way - osmdata->start_way) : 1.0) : 0.0,
330            osmdata->count_rel,
331            osmdata->count_rel > 0 ? (double)osmdata->count_rel/
332            ((double)(end_rel - osmdata->start_rel) > 0.0 ? (double)(end_rel - osmdata->start_rel) : 1.0) : 0.0);
333}
334
335int node_wanted(struct osmdata_t *osmdata, double lat, double lon)
336{
337    if (!osmdata->bbox)
338        return 1;
339
340    if (lat < osmdata->minlat || lat > osmdata->maxlat)
341        return 0;
342    if (lon < osmdata->minlon || lon > osmdata->maxlon)
343        return 0;
344    return 1;
345}
346
347int main(int argc, char *argv[])
348{
349    int append=0;
350    int create=0;
351    int slim=0;
352    int sanitize=0;
353    int long_usage_bool=0;
354    int pass_prompt=0;
355    int projection = PROJ_SPHERE_MERC;
356    int expire_tiles_zoom = -1;
357    int expire_tiles_zoom_min = -1;
358    int enable_hstore = HSTORE_NONE;
359    int enable_hstore_index = 0;
360    int hstore_match_only = 0;
361    int enable_multi = 0;
362    int parallel_indexing = 1;
363    int flat_node_cache_enabled = 0;
364#ifdef __amd64__
365    int alloc_chunkwise = ALLOC_SPARSE | ALLOC_DENSE;
366#else
367    int alloc_chunkwise = ALLOC_SPARSE;
368#endif
369    int num_procs = 1;
370    int droptemp = 0;
371    int unlogged = 0;
372    int excludepoly = 0;
373    time_t start, end;
374    time_t overall_start, overall_end;
375    time_t now;
376    time_t end_nodes;
377    time_t end_way;
378    time_t end_rel;
379    const char *expire_tiles_filename = "dirty_tiles";
380    const char *db = "gis";
381    const char *username=NULL;
382    const char *host=NULL;
383    const char *password=NULL;
384    const char *port = "5432";
385    const char *tblsmain_index = NULL; /* no default TABLESPACE for index on main tables */
386    const char *tblsmain_data = NULL;  /* no default TABLESPACE for main tables */
387    const char *tblsslim_index = NULL; /* no default TABLESPACE for index on slim mode tables */
388    const char *tblsslim_data = NULL;  /* no default TABLESPACE for slim mode tables */
389    const char *conninfo = NULL;
390    const char *prefix = "planet_osm";
391    const char *style = OSM2PGSQL_DATADIR "/default.style";
392    const char *temparg;
393    const char *output_backend = "pgsql";
394    const char *input_reader = "auto";
395    const char **hstore_columns = NULL;
396    const char *flat_nodes_file = NULL;
397    int n_hstore_columns = 0;
398    int keep_coastlines=0;
399    int cache = 800;
400    struct output_options options;
401    PGconn *sql_conn;
402   
403    int (*streamFile)(char *, int, struct osmdata_t *);
404
405    fprintf(stderr, "osm2pgsql SVN version %s (%lubit id space)\n\n", VERSION, 8 * sizeof(osmid_t));
406
407    while (1) {
408        int c, option_index = 0;
409        static struct option long_options[] = {
410            {"append",   0, 0, 'a'},
411            {"bbox",     1, 0, 'b'},
412            {"create",   0, 0, 'c'},
413            {"database", 1, 0, 'd'},
414            {"latlong",  0, 0, 'l'},
415            {"verbose",  0, 0, 'v'},
416            {"slim",     0, 0, 's'},
417            {"prefix",   1, 0, 'p'},
418            {"proj",     1, 0, 'E'},
419            {"merc",     0, 0, 'm'},
420            {"oldmerc",  0, 0, 'M'},
421            {"utf8-sanitize", 0, 0, 'u'},
422            {"cache",    1, 0, 'C'},
423            {"username", 1, 0, 'U'},
424            {"password", 0, 0, 'W'},
425            {"host",     1, 0, 'H'},
426            {"port",     1, 0, 'P'},
427            {"tablespace-index", 1, 0, 'i'},
428            {"tablespace-slim-data", 1, 0, 200},
429            {"tablespace-slim-index", 1, 0, 201},
430            {"tablespace-main-data", 1, 0, 202},
431            {"tablespace-main-index", 1, 0, 203},
432            {"help",     0, 0, 'h'},
433            {"style",    1, 0, 'S'},
434            {"expire-tiles", 1, 0, 'e'},
435            {"expire-output", 1, 0, 'o'},
436            {"output",   1, 0, 'O'},
437            {"extra-attributes", 0, 0, 'x'},
438            {"hstore", 0, 0, 'k'},
439            {"hstore-all", 0, 0, 'j'},
440            {"hstore-column", 1, 0, 'z'},
441            {"hstore-match-only", 0, 0, 208},
442            {"hstore-add-index",0,0,211},
443            {"multi-geometry", 0, 0, 'G'},
444            {"keep-coastlines", 0, 0, 'K'},
445            {"input-reader", 1, 0, 'r'},
446            {"version", 0, 0, 'V'},
447            {"disable-parallel-indexing", 0, 0, 'I'},
448            {"cache-strategy", 1, 0, 204},
449            {"number-processes", 1, 0, 205},
450            {"drop", 0, 0, 206},
451            {"unlogged", 0, 0, 207},
452            {"flat-nodes",1,0,209},
453            {"exclude-invalid-polygon",0,0,210},
454            {0, 0, 0, 0}
455        };
456
457        c = getopt_long (argc, argv, "ab:cd:KhlmMp:suvU:WH:P:i:IE:C:S:e:o:O:xkjGz:r:V", long_options, &option_index);
458        if (c == -1)
459            break;
460
461        switch (c) {
462            case 'a': append=1;   break;
463            case 'b': osmdata.bbox=optarg; break;
464            case 'c': create=1;   break;
465            case 'v': verbose=1;  break;
466            case 's': slim=1;     break;
467            case 'K': keep_coastlines=1;     break;
468            case 'u': sanitize=1; break;
469            case 'l': projection=PROJ_LATLONG;  break;
470            case 'm': projection=PROJ_SPHERE_MERC; break;
471            case 'M': projection=PROJ_MERC; break;
472            case 'E': projection=-atoi(optarg); break;
473            case 'p': prefix=optarg; break;
474            case 'd': db=optarg;  break;
475            case 'C': cache = atoi(optarg); break;
476            case 'U': username=optarg; break;
477            case 'W': pass_prompt=1; break;
478            case 'H': host=optarg; break;
479            case 'P': port=optarg; break;
480            case 'S': style=optarg; break;
481            case 'i': tblsmain_index=tblsslim_index=optarg; break;
482            case 200: tblsslim_data=optarg; break;   
483            case 201: tblsslim_index=optarg; break;   
484            case 202: tblsmain_data=optarg; break;   
485            case 203: tblsmain_index=optarg; break;   
486            case 'e':
487                expire_tiles_zoom_min = atoi(optarg);
488                temparg = strchr(optarg, '-');
489                if (temparg) expire_tiles_zoom = atoi(temparg + 1);
490                if (expire_tiles_zoom < expire_tiles_zoom_min) expire_tiles_zoom = expire_tiles_zoom_min;
491                break;
492            case 'o': expire_tiles_filename=optarg; break;
493            case 'O': output_backend = optarg; break;
494            case 'x': osmdata.extra_attributes=1; break;
495            case 'k': enable_hstore=HSTORE_NORM; break;
496            case 208: hstore_match_only = 1; break;
497            case 'j': enable_hstore=HSTORE_ALL; break;
498            case 'z': 
499                n_hstore_columns++;
500                hstore_columns = (const char**)realloc(hstore_columns, sizeof(char *) * n_hstore_columns);
501                hstore_columns[n_hstore_columns-1] = optarg;
502                break;
503            case 'G': enable_multi=1; break;
504            case 'r': input_reader = optarg; break;
505            case 'h': long_usage_bool=1; break;
506            case 'I': 
507#ifdef HAVE_PTHREAD
508                parallel_indexing=0; 
509#endif
510                break;
511            case 204:
512                if (strcmp(optarg,"dense") == 0) alloc_chunkwise = ALLOC_DENSE;
513                if (strcmp(optarg,"chunk") == 0) alloc_chunkwise = ALLOC_DENSE | ALLOC_DENSE_CHUNK;
514                if (strcmp(optarg,"sparse") == 0) alloc_chunkwise = ALLOC_SPARSE;
515                if (strcmp(optarg,"optimized") == 0) alloc_chunkwise = ALLOC_DENSE | ALLOC_SPARSE;
516                break;
517            case 205:
518#ifdef HAVE_FORK               
519                num_procs = atoi(optarg);
520#else
521                fprintf(stderr, "WARNING: osm2pgsql was compiled without fork, only using one process!\n");
522#endif
523                break;
524            case 206: droptemp = 1; break;
525            case 207: unlogged = 1; break;
526            case 209:
527                flat_node_cache_enabled = 1;
528                flat_nodes_file = optarg;
529                break;
530            case 210: excludepoly = 1; exclude_broken_polygon(); break;
531            case 211: enable_hstore_index = 1; break;
532            case 'V': exit(EXIT_SUCCESS);
533            case '?':
534            default:
535                short_usage(argv[0]);
536                exit(EXIT_FAILURE);
537        }
538    }
539
540    if (long_usage_bool) {
541        long_usage(argv[0]);
542        exit(EXIT_SUCCESS);
543    }
544
545    if (argc == optind) {  /* No non-switch arguments */
546        short_usage(argv[0]);
547        exit(EXIT_FAILURE);
548    }
549
550    if (append && create) {
551        fprintf(stderr, "Error: --append and --create options can not be used at the same time!\n");
552        exit(EXIT_FAILURE);
553    }
554
555    if (droptemp && !slim) {
556        fprintf(stderr, "Error: --drop only makes sense with --slim.\n");
557        exit(EXIT_FAILURE);
558    }
559
560    if (unlogged && !create) {
561        fprintf(stderr, "Warning: --unlogged only makes sense with --create; ignored.\n");
562        unlogged = 0;
563    }
564
565    if (enable_hstore == HSTORE_NONE && !n_hstore_columns && hstore_match_only)
566    {
567        fprintf(stderr, "Warning: --hstore-match-only only makes sense with --hstore, --hstore-all, or --hstore-column; ignored.\n");
568        hstore_match_only = 0;
569    }
570
571    if (enable_hstore_index && enable_hstore  == HSTORE_NONE && !n_hstore_columns) {
572        fprintf(stderr, "Warning: --hstore-add-index only makes sense with hstore enabled.\n");
573        enable_hstore_index = 0;
574    }
575
576    if (cache < 0) cache = 0;
577
578    if (num_procs < 1) num_procs = 1;
579
580    if (pass_prompt)
581        password = simple_prompt("Password:", 100, 0);
582    else {
583        password = getenv("PGPASS");
584    }
585
586   
587
588    conninfo = build_conninfo(db, username, password, host, port);
589    sql_conn = PQconnectdb(conninfo);
590    if (PQstatus(sql_conn) != CONNECTION_OK) {
591        fprintf(stderr, "Error: Connection to database failed: %s\n", PQerrorMessage(sql_conn));
592        exit(EXIT_FAILURE);
593    }
594    if (unlogged && PQserverVersion(sql_conn) < 90100) {
595        fprintf(stderr, "Error: --unlogged works only with PostgreSQL 9.1 and above, but\n");
596        fprintf(stderr, "you are using PostgreSQL %d.%d.%d.\n", PQserverVersion(sql_conn) / 10000, (PQserverVersion(sql_conn) / 100) % 100, PQserverVersion(sql_conn) % 100);
597        exit(EXIT_FAILURE);
598    }
599
600    PQfinish(sql_conn);
601
602    text_init();
603    initList(&osmdata.tags);
604
605    osmdata.count_node = osmdata.max_node = 0;
606    osmdata.count_way  = osmdata.max_way  = 0;
607    osmdata.count_rel  = osmdata.max_rel  = 0;
608
609    LIBXML_TEST_VERSION
610
611    project_init(projection);
612    fprintf(stderr, "Using projection SRS %d (%s)\n", 
613        project_getprojinfo()->srs, project_getprojinfo()->descr );
614
615    if (parse_bbox(&osmdata))
616        return 1;
617
618    options.conninfo = conninfo;
619    options.prefix = prefix;
620    options.append = append;
621    options.slim = slim;
622    options.projection = project_getprojinfo()->srs;
623    options.scale = (projection==PROJ_LATLONG)?10000000:100;
624    options.mid = slim ? &mid_pgsql : &mid_ram;
625    options.cache = cache;
626    options.style = style;
627    options.tblsmain_index = tblsmain_index;
628    options.tblsmain_data = tblsmain_data;
629    options.tblsslim_index = tblsslim_index;
630    options.tblsslim_data = tblsslim_data;
631    options.expire_tiles_zoom = expire_tiles_zoom;
632    options.expire_tiles_zoom_min = expire_tiles_zoom_min;
633    options.expire_tiles_filename = expire_tiles_filename;
634    options.enable_multi = enable_multi;
635    options.enable_hstore = enable_hstore;
636    options.enable_hstore_index = enable_hstore_index;
637    options.hstore_match_only = hstore_match_only;
638    options.hstore_columns = hstore_columns;
639    options.n_hstore_columns = n_hstore_columns;
640    options.keep_coastlines = keep_coastlines;
641    options.parallel_indexing = parallel_indexing;
642    options.alloc_chunkwise = alloc_chunkwise;
643    options.num_procs = num_procs;
644    options.droptemp = droptemp;
645    options.unlogged = unlogged;
646    options.flat_node_cache_enabled = flat_node_cache_enabled;
647    options.flat_node_file = flat_nodes_file;
648    options.excludepoly = excludepoly;
649
650    if (strcmp("pgsql", output_backend) == 0) {
651      osmdata.out = &out_pgsql;
652    } else if (strcmp("gazetteer", output_backend) == 0) {
653      osmdata.out = &out_gazetteer;
654    } else if (strcmp("null", output_backend) == 0) {
655      osmdata.out = &out_null;
656    } else {
657      fprintf(stderr, "Output backend `%s' not recognised. Should be one of [pgsql, gazetteer, null].\n", output_backend);
658      exit(EXIT_FAILURE);
659    }
660    options.out = osmdata.out;
661
662    if (strcmp("auto", input_reader) != 0) {
663      if (strcmp("libxml2", input_reader) == 0) {
664        streamFile = &streamFileXML2;
665      } else if (strcmp("primitive", input_reader) == 0) {
666        streamFile = &streamFilePrimitive;
667#ifdef BUILD_READER_PBF
668      } else if (strcmp("pbf", input_reader) == 0) {
669        streamFile = &streamFilePbf;
670#endif
671      } else if (strcmp("o5m", input_reader) == 0) {
672          streamFile = &streamFileO5m;
673      } else {
674        fprintf(stderr, "Input parser `%s' not recognised. Should be one of [libxml2, primitive, o5m"
675#ifdef BUILD_READER_PBF
676              ", pbf"
677#endif
678              "].\n", input_reader);
679      exit(EXIT_FAILURE);
680      }
681    }
682
683    time(&overall_start);
684    osmdata.out->start(&options);
685
686    realloc_nodes(&osmdata);
687    realloc_members(&osmdata);
688
689    if (sizeof(int*) == 4 && options.slim != 1) {
690        fprintf(stderr, "\n!! You are running this on 32bit system, so at most\n");
691        fprintf(stderr, "!! 3GB of RAM can be used. If you encounter unexpected\n");
692        fprintf(stderr, "!! exceptions during import, you should try running in slim\n");
693        fprintf(stderr, "!! mode using parameter -s.\n");
694    }
695
696    while (optind < argc) {
697        /* if input_reader is not forced by -r switch try to auto-detect it
698           by file extension */
699        if (strcmp("auto", input_reader) == 0) {
700
701          if (strcasecmp(".pbf",argv[optind]+strlen(argv[optind])-4) == 0) {
702#ifdef BUILD_READER_PBF
703            streamFile = &streamFilePbf;
704#else
705            fprintf(stderr, "ERROR: PBF support has not been compiled into this version of osm2pgsql, please either compile it with pbf support or use one of the other input formats\n");
706            exit(EXIT_FAILURE);
707#endif
708          } else if (strcasecmp(".o5m",argv[optind]+strlen(argv[optind])-4) == 0) {
709              streamFile = &streamFileO5m;
710          } else {
711            streamFile = &streamFileXML2;
712          }
713        }
714        fprintf(stderr, "\nReading in file: %s\n", argv[optind]);
715        time(&start);
716        if (streamFile(argv[optind], sanitize, &osmdata) != 0)
717            exit_nicely();
718        time(&end);
719        fprintf(stderr, "  parse time: %ds\n", (int)(end - start));
720        optind++;
721    }
722
723    xmlCleanupParser();
724    xmlMemoryDump();
725   
726    if (osmdata.count_node || osmdata.count_way || osmdata.count_rel) {
727        time(&now);
728        end_nodes = osmdata.start_way > 0 ? osmdata.start_way : now;
729        end_way = osmdata.start_rel > 0 ? osmdata.start_rel : now;
730        end_rel =  now;
731        fprintf(stderr, "\n");
732        fprintf(stderr, "Node stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_node, osmdata.max_node,
733                osmdata.count_node > 0 ? (int)(end_nodes - osmdata.start_node) : 0);
734        fprintf(stderr, "Way stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_way, osmdata.max_way,
735                osmdata.count_way > 0 ? (int)(end_way - osmdata.start_way) : 0);
736        fprintf(stderr, "Relation stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_rel, osmdata.max_rel,
737                osmdata.count_rel > 0 ? (int)(end_rel - osmdata.start_rel) : 0);
738    }
739    osmdata.out->stop();
740   
741    free(osmdata.nds);
742    free(osmdata.members);
743   
744    /* free the column pointer buffer */
745    free(hstore_columns);
746
747    project_exit();
748    text_exit();
749    fprintf(stderr, "\n");
750    time(&overall_end);
751    fprintf(stderr, "Osm2pgsql took %ds overall\n", (int)(overall_end - overall_start));
752
753    return 0;
754}
Note: See TracBrowser for help on using the repository browser.