/** * Range search returns number of points found, with results in nearest * Normal is optional, but if given will limit results to points in normal direction from co. * Remember to free nearest after use! */ int BLI_kdtree_range_search__normal( const KDTree *tree, const float co[3], const float nor[3], KDTreeNearest **r_nearest, float range) { const KDTreeNode *nodes = tree->nodes; uint *stack, defaultstack[KD_STACK_INIT]; KDTreeNearest *foundstack = NULL; float range_sq = range * range, dist_sq; uint totstack, cur = 0, found = 0, totfoundstack = 0; #ifdef DEBUG BLI_assert(tree->is_balanced == true); #endif if (UNLIKELY(tree->root == KD_NODE_UNSET)) return 0; stack = defaultstack; totstack = KD_STACK_INIT; stack[cur++] = tree->root; while (cur--) { const KDTreeNode *node = &nodes[stack[cur]]; if (co[node->d] + range < node->co[node->d]) { if (node->left != KD_NODE_UNSET) stack[cur++] = node->left; } else if (co[node->d] - range > node->co[node->d]) { if (node->right != KD_NODE_UNSET) stack[cur++] = node->right; } else { dist_sq = squared_distance(node->co, co, nor); if (dist_sq <= range_sq) { add_in_range(&foundstack, &totfoundstack, found++, node->index, dist_sq, node->co); } if (node->left != KD_NODE_UNSET) stack[cur++] = node->left; if (node->right != KD_NODE_UNSET) stack[cur++] = node->right; } if (UNLIKELY(cur + 3 > totstack)) { stack = realloc_nodes(stack, &totstack, defaultstack != stack); } } if (stack != defaultstack) MEM_freeN(stack); if (found) qsort(foundstack, found, sizeof(KDTreeNearest), range_compare); *r_nearest = foundstack; return (int)found; }
/** * A version of #BLI_kdtree_range_search which runs a callback * instead of allocating an array. * * \param search_cb: Called for every node found in \a range, false return value performs an early exit. * * \note the order of calls isn't sorted based on distance. */ void BLI_kdtree_range_search_cb( const KDTree *tree, const float co[3], float range, bool (*search_cb)(void *user_data, int index, const float co[3], float dist_sq), void *user_data) { const KDTreeNode *nodes = tree->nodes; uint *stack, defaultstack[KD_STACK_INIT]; float range_sq = range * range, dist_sq; uint totstack, cur = 0; #ifdef DEBUG BLI_assert(tree->is_balanced == true); #endif if (UNLIKELY(tree->root == KD_NODE_UNSET)) return; stack = defaultstack; totstack = KD_STACK_INIT; stack[cur++] = tree->root; while (cur--) { const KDTreeNode *node = &nodes[stack[cur]]; if (co[node->d] + range < node->co[node->d]) { if (node->left != KD_NODE_UNSET) stack[cur++] = node->left; } else if (co[node->d] - range > node->co[node->d]) { if (node->right != KD_NODE_UNSET) stack[cur++] = node->right; } else { dist_sq = len_squared_v3v3(node->co, co); if (dist_sq <= range_sq) { if (search_cb(user_data, node->index, node->co, dist_sq) == false) { goto finally; } } if (node->left != KD_NODE_UNSET) stack[cur++] = node->left; if (node->right != KD_NODE_UNSET) stack[cur++] = node->right; } if (UNLIKELY(cur + 3 > totstack)) { stack = realloc_nodes(stack, &totstack, defaultstack != stack); } } finally: if (stack != defaultstack) MEM_freeN(stack); }
static void StartElement(xmlTextReaderPtr reader, const xmlChar *name, struct osmdata_t *osmdata) { xmlChar *xid, *xlat, *xlon, *xk, *xv, *xrole, *xtype; char *k; if (osmdata->filetype == FILETYPE_NONE) { if (xmlStrEqual(name, BAD_CAST "osm")) { osmdata->filetype = FILETYPE_OSM; osmdata->action = ACTION_CREATE; } else if (xmlStrEqual(name, BAD_CAST "osmChange")) { osmdata->filetype = FILETYPE_OSMCHANGE; osmdata->action = ACTION_NONE; } else if (xmlStrEqual(name, BAD_CAST "planetdiff")) { osmdata->filetype = FILETYPE_PLANETDIFF; osmdata->action = ACTION_NONE; } else { fprintf( stderr, "Unknown XML document type: %s\n", name ); exit_nicely(); } return; } if (xmlStrEqual(name, BAD_CAST "node")) { xid = xmlTextReaderGetAttribute(reader, BAD_CAST "id"); xlon = xmlTextReaderGetAttribute(reader, BAD_CAST "lon"); xlat = xmlTextReaderGetAttribute(reader, BAD_CAST "lat"); assert(xid); assert(xlon); assert(xlat); osmdata->osm_id = strtol((char *)xid, NULL, 10); osmdata->node_lon = strtod((char *)xlon, NULL); osmdata->node_lat = strtod((char *)xlat, NULL); osmdata->action = ParseAction( reader , osmdata); if (osmdata->osm_id > osmdata->max_node) osmdata->max_node = osmdata->osm_id; osmdata->count_node++; if (osmdata->count_node%10000 == 0) printStatus(osmdata); xmlFree(xid); xmlFree(xlon); xmlFree(xlat); } else if (xmlStrEqual(name, BAD_CAST "tag")) { xk = xmlTextReaderGetAttribute(reader, BAD_CAST "k"); assert(xk); /* 'created_by' and 'source' are common and not interesting to mapnik renderer */ if (strcmp((char *)xk, "created_by") && strcmp((char *)xk, "source")) { char *p; xv = xmlTextReaderGetAttribute(reader, BAD_CAST "v"); assert(xv); k = (char *)xmlStrdup(xk); while ((p = strchr(k, ' '))) *p = '_'; addItem(&(osmdata->tags), k, (char *)xv, 0); xmlFree(k); xmlFree(xv); } xmlFree(xk); } else if (xmlStrEqual(name, BAD_CAST "way")) { xid = xmlTextReaderGetAttribute(reader, BAD_CAST "id"); assert(xid); osmdata->osm_id = strtol((char *)xid, NULL, 10); osmdata->action = ParseAction( reader, osmdata ); if (osmdata->osm_id > osmdata->max_way) osmdata->max_way = osmdata->osm_id; osmdata->count_way++; if (osmdata->count_way%1000 == 0) printStatus(osmdata); osmdata->nd_count = 0; xmlFree(xid); } else if (xmlStrEqual(name, BAD_CAST "nd")) { xid = xmlTextReaderGetAttribute(reader, BAD_CAST "ref"); assert(xid); osmdata->nds[osmdata->nd_count++] = strtol( (char *)xid, NULL, 10 ); if( osmdata->nd_count >= osmdata->nd_max ) realloc_nodes(osmdata); xmlFree(xid); } else if (xmlStrEqual(name, BAD_CAST "relation")) { xid = xmlTextReaderGetAttribute(reader, BAD_CAST "id"); assert(xid); osmdata->osm_id = strtol((char *)xid, NULL, 10); osmdata->action = ParseAction( reader, osmdata ); if (osmdata->osm_id > osmdata->max_rel) osmdata->max_rel = osmdata->osm_id; osmdata->count_rel++; if (osmdata->count_rel%10 == 0) printStatus(osmdata); osmdata->member_count = 0; xmlFree(xid); } else if (xmlStrEqual(name, BAD_CAST "member")) { xrole = xmlTextReaderGetAttribute(reader, BAD_CAST "role"); assert(xrole); xtype = xmlTextReaderGetAttribute(reader, BAD_CAST "type"); assert(xtype); xid = xmlTextReaderGetAttribute(reader, BAD_CAST "ref"); assert(xid); osmdata->members[osmdata->member_count].id = strtol( (char *)xid, NULL, 0 ); osmdata->members[osmdata->member_count].role = strdup( (char *)xrole ); /* Currently we are only interested in 'way' members since these form polygons with holes */ if (xmlStrEqual(xtype, BAD_CAST "way")) osmdata->members[osmdata->member_count].type = OSMTYPE_WAY; if (xmlStrEqual(xtype, BAD_CAST "node")) osmdata->members[osmdata->member_count].type = OSMTYPE_NODE; if (xmlStrEqual(xtype, BAD_CAST "relation")) osmdata->members[osmdata->member_count].type = OSMTYPE_RELATION; osmdata->member_count++; if( osmdata->member_count >= osmdata->member_max ) realloc_members(osmdata); xmlFree(xid); xmlFree(xrole); xmlFree(xtype); } else if (xmlStrEqual(name, BAD_CAST "add") || xmlStrEqual(name, BAD_CAST "create")) { osmdata->action = ACTION_MODIFY; // Turns all creates into modifies, makes it resiliant against inconsistant snapshots. } else if (xmlStrEqual(name, BAD_CAST "modify")) { osmdata->action = ACTION_MODIFY; } else if (xmlStrEqual(name, BAD_CAST "delete")) { osmdata->action = ACTION_DELETE; } else if (xmlStrEqual(name, BAD_CAST "bound")) { /* ignore */ } else if (xmlStrEqual(name, BAD_CAST "bounds")) { /* ignore */ } else if (xmlStrEqual(name, BAD_CAST "changeset")) { /* ignore */ } else { fprintf(stderr, "%s: Unknown element name: %s\n", __FUNCTION__, name); } // Collect extra attribute information and add as tags if (osmdata->extra_attributes && (xmlStrEqual(name, BAD_CAST "node") || xmlStrEqual(name, BAD_CAST "way") || xmlStrEqual(name, BAD_CAST "relation"))) { xmlChar *xtmp; xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "user"); if (xtmp) { addItem(&(osmdata->tags), "osm_user", (char *)xtmp, 0); xmlFree(xtmp); } xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "uid"); if (xtmp) { addItem(&(osmdata->tags), "osm_uid", (char *)xtmp, 0); xmlFree(xtmp); } xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "version"); if (xtmp) { addItem(&(osmdata->tags), "osm_version", (char *)xtmp, 0); xmlFree(xtmp); } xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "timestamp"); if (xtmp) { addItem(&(osmdata->tags), "osm_timestamp", (char *)xtmp, 0); xmlFree(xtmp); } } }
static void StartElement(char *name, char *line, struct osmdata_t *osmdata) { char *xid, *xlat, *xlon, *xk, *xv, *xrole, *xtype; char *token[255]; int tokens = 0; int quote = 0; char *i; if (osmdata->filetype == FILETYPE_NONE) { if (!strcmp(name, "?xml")) return; if (!strcmp(name, "osm")) { osmdata->filetype = FILETYPE_OSM; osmdata->action = ACTION_CREATE; } else if (!strcmp(name, "osmChange")) { osmdata->filetype = FILETYPE_OSMCHANGE; osmdata->action = ACTION_NONE; } else if (!strcmp(name, "planetdiff")) { osmdata->filetype = FILETYPE_PLANETDIFF; osmdata->action = ACTION_NONE; } else { fprintf( stderr, "Unknown XML document type: %s\n", name ); exit_nicely(); } return; } tokens=1; token[0] = line; for (i=line; *i; i++) { if (quote) { if (*i == '"') { quote = 0; } } else { if (*i == '"') { quote = 1; } else if (isspace(*i)) { *i = 0; token[tokens++] = i + 1; } } } if (!strcmp(name, "node")) { xid = extractAttribute(token, tokens, "id"); xlon = extractAttribute(token, tokens, "lon"); xlat = extractAttribute(token, tokens, "lat"); assert(xid); assert(xlon); assert(xlat); osmdata->osm_id = strtoosmid((char *)xid, NULL, 10); osmdata->node_lon = strtod((char *)xlon, NULL); osmdata->node_lat = strtod((char *)xlat, NULL); osmdata->action = ParseAction(token, tokens, osmdata); if (osmdata->osm_id > osmdata->max_node) osmdata->max_node = osmdata->osm_id; if (osmdata->count_node == 0) { time(&osmdata->start_node); } osmdata->count_node++; if (osmdata->count_node%10000 == 0) printStatus(osmdata); } else if (!strcmp(name, "tag")) { xk = extractAttribute(token, tokens, "k"); assert(xk); /* 'created_by' and 'source' are common and not interesting to mapnik renderer */ if (strcmp((char *)xk, "created_by") && strcmp((char *)xk, "source")) { char *p; xv = extractAttribute(token, tokens, "v"); assert(xv); while ((p = strchr(xk, ' '))) *p = '_'; addItem(&(osmdata->tags), xk, (char *)xv, 0); } } else if (!strcmp(name, "way")) { xid = extractAttribute(token, tokens, "id"); assert(xid); osmdata->osm_id = strtoosmid((char *)xid, NULL, 10); osmdata->action = ParseAction(token, tokens, osmdata); if (osmdata->osm_id > osmdata->max_way) osmdata->max_way = osmdata->osm_id; if (osmdata->count_way == 0) { time(&osmdata->start_way); } osmdata->count_way++; if (osmdata->count_way%1000 == 0) printStatus(osmdata); osmdata->nd_count = 0; } else if (!strcmp(name, "nd")) { xid = extractAttribute(token, tokens, "ref"); assert(xid); osmdata->nds[osmdata->nd_count++] = strtoosmid( (char *)xid, NULL, 10 ); if( osmdata->nd_count >= osmdata->nd_max ) realloc_nodes(osmdata); } else if (!strcmp(name, "relation")) { xid = extractAttribute(token, tokens, "id"); assert(xid); osmdata->osm_id = strtoosmid((char *)xid, NULL, 10); osmdata->action = ParseAction(token, tokens, osmdata); if (osmdata->osm_id > osmdata->max_rel) osmdata->max_rel = osmdata->osm_id; if (osmdata->count_rel == 0) { time(&osmdata->start_rel); } osmdata->count_rel++; if (osmdata->count_rel%10 == 0) printStatus(osmdata); osmdata->member_count = 0; } else if (!strcmp(name, "member")) { xrole = extractAttribute(token, tokens, "role"); assert(xrole); xtype = extractAttribute(token, tokens, "type"); assert(xtype); xid = extractAttribute(token, tokens, "ref"); assert(xid); osmdata->members[osmdata->member_count].id = strtoosmid( (char *)xid, NULL, 0 ); osmdata->members[osmdata->member_count].role = strdup( (char *)xrole ); /* Currently we are only interested in 'way' members since these form polygons with holes */ if (!strcmp(xtype, "way")) osmdata->members[osmdata->member_count].type = OSMTYPE_WAY; else if (!strcmp(xtype, "node")) osmdata->members[osmdata->member_count].type = OSMTYPE_NODE; else if (!strcmp(xtype, "relation")) osmdata->members[osmdata->member_count].type = OSMTYPE_RELATION; osmdata->member_count++; if( osmdata->member_count >= osmdata->member_max ) realloc_members(osmdata); } else if (!strcmp(name, "add") || !strcmp(name, "create")) { osmdata->action = ACTION_MODIFY; /* Turns all creates into modifies, makes it resiliant against inconsistant snapshots. */ } else if (!strcmp(name, "modify")) { osmdata->action = ACTION_MODIFY; } else if (!strcmp(name, "delete")) { osmdata->action = ACTION_DELETE; } else if (!strcmp(name, "bound")) { /* ignore */ } else if (!strcmp(name, "bounds")) { /* ignore */ } else if (!strcmp(name, "changeset")) { /* ignore */ } else { fprintf(stderr, "%s: Unknown element name: %s\n", __FUNCTION__, name); } /* Collect extra attribute information and add as tags */ if (osmdata->extra_attributes && (!strcmp(name, "node") || !strcmp(name, "way") || !strcmp(name, "relation"))) { char *xtmp; xtmp = extractAttribute(token, tokens, "user"); if (xtmp) { addItem(&(osmdata->tags), "osm_user", (char *)xtmp, 0); } xtmp = extractAttribute(token, tokens, "uid"); if (xtmp) { addItem(&(osmdata->tags), "osm_uid", (char *)xtmp, 0); } xtmp = extractAttribute(token, tokens, "version"); if (xtmp) { addItem(&(osmdata->tags), "osm_version", (char *)xtmp, 0); } xtmp = extractAttribute(token, tokens, "timestamp"); if (xtmp) { addItem(&(osmdata->tags), "osm_timestamp", (char *)xtmp, 0); } } }
int main(int argc, char *argv[]) { int append=0; int create=0; int slim=0; int sanitize=0; int long_usage_bool=0; int pass_prompt=0; int projection = PROJ_SPHERE_MERC; int expire_tiles_zoom = -1; int expire_tiles_zoom_min = -1; int enable_hstore = HSTORE_NONE; int enable_hstore_index = 0; int hstore_match_only = 0; int enable_multi = 0; int parallel_indexing = 1; int flat_node_cache_enabled = 0; #ifdef __amd64__ int alloc_chunkwise = ALLOC_SPARSE | ALLOC_DENSE; #else int alloc_chunkwise = ALLOC_SPARSE; #endif int num_procs = 1; int droptemp = 0; int unlogged = 0; int excludepoly = 0; time_t start, end; time_t overall_start, overall_end; time_t now; time_t end_nodes; time_t end_way; time_t end_rel; const char *expire_tiles_filename = "dirty_tiles"; const char *db = "gis"; const char *username=NULL; const char *host=NULL; const char *password=NULL; const char *port = "5432"; const char *tblsmain_index = NULL; /* no default TABLESPACE for index on main tables */ const char *tblsmain_data = NULL; /* no default TABLESPACE for main tables */ const char *tblsslim_index = NULL; /* no default TABLESPACE for index on slim mode tables */ const char *tblsslim_data = NULL; /* no default TABLESPACE for slim mode tables */ const char *conninfo = NULL; const char *prefix = "planet_osm"; const char *style = OSM2PGSQL_DATADIR "/default.style"; const char *temparg; const char *output_backend = "pgsql"; const char *input_reader = "auto"; const char **hstore_columns = NULL; const char *flat_nodes_file = NULL; const char *tag_transform_script = NULL; int n_hstore_columns = 0; int keep_coastlines=0; int cache = 800; struct output_options options; PGconn *sql_conn; int (*streamFile)(char *, int, struct osmdata_t *); fprintf(stderr, "osm2pgsql SVN version %s (%lubit id space)\n\n", VERSION, 8 * sizeof(osmid_t)); while (1) { int c, option_index = 0; static struct option long_options[] = { {"append", 0, 0, 'a'}, {"bbox", 1, 0, 'b'}, {"create", 0, 0, 'c'}, {"database", 1, 0, 'd'}, {"latlong", 0, 0, 'l'}, {"verbose", 0, 0, 'v'}, {"slim", 0, 0, 's'}, {"prefix", 1, 0, 'p'}, {"proj", 1, 0, 'E'}, {"merc", 0, 0, 'm'}, {"oldmerc", 0, 0, 'M'}, {"utf8-sanitize", 0, 0, 'u'}, {"cache", 1, 0, 'C'}, {"username", 1, 0, 'U'}, {"password", 0, 0, 'W'}, {"host", 1, 0, 'H'}, {"port", 1, 0, 'P'}, {"tablespace-index", 1, 0, 'i'}, {"tablespace-slim-data", 1, 0, 200}, {"tablespace-slim-index", 1, 0, 201}, {"tablespace-main-data", 1, 0, 202}, {"tablespace-main-index", 1, 0, 203}, {"help", 0, 0, 'h'}, {"style", 1, 0, 'S'}, {"expire-tiles", 1, 0, 'e'}, {"expire-output", 1, 0, 'o'}, {"output", 1, 0, 'O'}, {"extra-attributes", 0, 0, 'x'}, {"hstore", 0, 0, 'k'}, {"hstore-all", 0, 0, 'j'}, {"hstore-column", 1, 0, 'z'}, {"hstore-match-only", 0, 0, 208}, {"hstore-add-index",0,0,211}, {"multi-geometry", 0, 0, 'G'}, {"keep-coastlines", 0, 0, 'K'}, {"input-reader", 1, 0, 'r'}, {"version", 0, 0, 'V'}, {"disable-parallel-indexing", 0, 0, 'I'}, {"cache-strategy", 1, 0, 204}, {"number-processes", 1, 0, 205}, {"drop", 0, 0, 206}, {"unlogged", 0, 0, 207}, {"flat-nodes",1,0,209}, {"exclude-invalid-polygon",0,0,210}, {"tag-transform-script",1,0,212}, {0, 0, 0, 0} }; 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); if (c == -1) break; switch (c) { case 'a': append=1; break; case 'b': osmdata.bbox=optarg; break; case 'c': create=1; break; case 'v': verbose=1; break; case 's': slim=1; break; case 'K': keep_coastlines=1; break; case 'u': sanitize=1; break; case 'l': projection=PROJ_LATLONG; break; case 'm': projection=PROJ_SPHERE_MERC; break; case 'M': projection=PROJ_MERC; break; case 'E': projection=-atoi(optarg); break; case 'p': prefix=optarg; break; case 'd': db=optarg; break; case 'C': cache = atoi(optarg); break; case 'U': username=optarg; break; case 'W': pass_prompt=1; break; case 'H': host=optarg; break; case 'P': port=optarg; break; case 'S': style=optarg; break; case 'i': tblsmain_index=tblsslim_index=optarg; break; case 200: tblsslim_data=optarg; break; case 201: tblsslim_index=optarg; break; case 202: tblsmain_data=optarg; break; case 203: tblsmain_index=optarg; break; case 'e': expire_tiles_zoom_min = atoi(optarg); temparg = strchr(optarg, '-'); if (temparg) expire_tiles_zoom = atoi(temparg + 1); if (expire_tiles_zoom < expire_tiles_zoom_min) expire_tiles_zoom = expire_tiles_zoom_min; break; case 'o': expire_tiles_filename=optarg; break; case 'O': output_backend = optarg; break; case 'x': osmdata.extra_attributes=1; break; case 'k': enable_hstore=HSTORE_NORM; break; case 208: hstore_match_only = 1; break; case 'j': enable_hstore=HSTORE_ALL; break; case 'z': n_hstore_columns++; hstore_columns = (const char**)realloc(hstore_columns, sizeof(char *) * n_hstore_columns); hstore_columns[n_hstore_columns-1] = optarg; break; case 'G': enable_multi=1; break; case 'r': input_reader = optarg; break; case 'h': long_usage_bool=1; break; case 'I': #ifdef HAVE_PTHREAD parallel_indexing=0; #endif break; case 204: if (strcmp(optarg,"dense") == 0) alloc_chunkwise = ALLOC_DENSE; else if (strcmp(optarg,"chunk") == 0) alloc_chunkwise = ALLOC_DENSE | ALLOC_DENSE_CHUNK; else if (strcmp(optarg,"sparse") == 0) alloc_chunkwise = ALLOC_SPARSE; else if (strcmp(optarg,"optimized") == 0) alloc_chunkwise = ALLOC_DENSE | ALLOC_SPARSE; else {fprintf(stderr, "ERROR: Unrecognized cache strategy %s.\n", optarg); exit(EXIT_FAILURE); } break; case 205: #ifdef HAVE_FORK num_procs = atoi(optarg); #else fprintf(stderr, "WARNING: osm2pgsql was compiled without fork, only using one process!\n"); #endif break; case 206: droptemp = 1; break; case 207: unlogged = 1; break; case 209: flat_node_cache_enabled = 1; flat_nodes_file = optarg; break; case 210: excludepoly = 1; exclude_broken_polygon(); break; case 211: enable_hstore_index = 1; break; case 212: tag_transform_script = optarg; break; case 'V': exit(EXIT_SUCCESS); case '?': default: short_usage(argv[0]); exit(EXIT_FAILURE); } } if (long_usage_bool) { long_usage(argv[0]); exit(EXIT_SUCCESS); } if (argc == optind) { /* No non-switch arguments */ short_usage(argv[0]); exit(EXIT_FAILURE); } if (append && create) { fprintf(stderr, "Error: --append and --create options can not be used at the same time!\n"); exit(EXIT_FAILURE); } if (droptemp && !slim) { fprintf(stderr, "Error: --drop only makes sense with --slim.\n"); exit(EXIT_FAILURE); } if (unlogged && !create) { fprintf(stderr, "Warning: --unlogged only makes sense with --create; ignored.\n"); unlogged = 0; } if (enable_hstore == HSTORE_NONE && !n_hstore_columns && hstore_match_only) { fprintf(stderr, "Warning: --hstore-match-only only makes sense with --hstore, --hstore-all, or --hstore-column; ignored.\n"); hstore_match_only = 0; } if (enable_hstore_index && enable_hstore == HSTORE_NONE && !n_hstore_columns) { fprintf(stderr, "Warning: --hstore-add-index only makes sense with hstore enabled.\n"); enable_hstore_index = 0; } if (cache < 0) cache = 0; if (num_procs < 1) num_procs = 1; if (pass_prompt) password = simple_prompt("Password:"******"PGPASS"); } conninfo = build_conninfo(db, username, password, host, port); sql_conn = PQconnectdb(conninfo); if (PQstatus(sql_conn) != CONNECTION_OK) { fprintf(stderr, "Error: Connection to database failed: %s\n", PQerrorMessage(sql_conn)); exit(EXIT_FAILURE); } if (unlogged && PQserverVersion(sql_conn) < 90100) { fprintf(stderr, "Error: --unlogged works only with PostgreSQL 9.1 and above, but\n"); fprintf(stderr, "you are using PostgreSQL %d.%d.%d.\n", PQserverVersion(sql_conn) / 10000, (PQserverVersion(sql_conn) / 100) % 100, PQserverVersion(sql_conn) % 100); exit(EXIT_FAILURE); } PQfinish(sql_conn); text_init(); initList(&osmdata.tags); osmdata.count_node = osmdata.max_node = 0; osmdata.count_way = osmdata.max_way = 0; osmdata.count_rel = osmdata.max_rel = 0; LIBXML_TEST_VERSION project_init(projection); fprintf(stderr, "Using projection SRS %d (%s)\n", project_getprojinfo()->srs, project_getprojinfo()->descr ); if (parse_bbox(&osmdata)) return 1; options.conninfo = conninfo; options.prefix = prefix; options.append = append; options.slim = slim; options.projection = project_getprojinfo()->srs; options.scale = (projection==PROJ_LATLONG)?10000000:100; options.mid = slim ? &mid_pgsql : &mid_ram; options.cache = cache; options.style = style; options.tblsmain_index = tblsmain_index; options.tblsmain_data = tblsmain_data; options.tblsslim_index = tblsslim_index; options.tblsslim_data = tblsslim_data; options.expire_tiles_zoom = expire_tiles_zoom; options.expire_tiles_zoom_min = expire_tiles_zoom_min; options.expire_tiles_filename = expire_tiles_filename; options.enable_multi = enable_multi; options.enable_hstore = enable_hstore; options.enable_hstore_index = enable_hstore_index; options.hstore_match_only = hstore_match_only; options.hstore_columns = hstore_columns; options.n_hstore_columns = n_hstore_columns; options.keep_coastlines = keep_coastlines; options.parallel_indexing = parallel_indexing; options.alloc_chunkwise = alloc_chunkwise; options.num_procs = num_procs; options.droptemp = droptemp; options.unlogged = unlogged; options.flat_node_cache_enabled = flat_node_cache_enabled; options.flat_node_file = flat_nodes_file; options.excludepoly = excludepoly; options.tag_transform_script = tag_transform_script; if (strcmp("pgsql", output_backend) == 0) { osmdata.out = &out_pgsql; } else if (strcmp("gazetteer", output_backend) == 0) { osmdata.out = &out_gazetteer; } else if (strcmp("null", output_backend) == 0) { osmdata.out = &out_null; } else { fprintf(stderr, "Output backend `%s' not recognised. Should be one of [pgsql, gazetteer, null].\n", output_backend); exit(EXIT_FAILURE); } options.out = osmdata.out; if (strcmp("auto", input_reader) != 0) { if (strcmp("libxml2", input_reader) == 0) { streamFile = &streamFileXML2; } else if (strcmp("primitive", input_reader) == 0) { streamFile = &streamFilePrimitive; #ifdef BUILD_READER_PBF } else if (strcmp("pbf", input_reader) == 0) { streamFile = &streamFilePbf; #endif } else if (strcmp("o5m", input_reader) == 0) { streamFile = &streamFileO5m; } else { fprintf(stderr, "Input parser `%s' not recognised. Should be one of [libxml2, primitive, o5m" #ifdef BUILD_READER_PBF ", pbf" #endif "].\n", input_reader); exit(EXIT_FAILURE); } } time(&overall_start); osmdata.out->start(&options); realloc_nodes(&osmdata); realloc_members(&osmdata); if (sizeof(int*) == 4 && options.slim != 1) { fprintf(stderr, "\n!! You are running this on 32bit system, so at most\n"); fprintf(stderr, "!! 3GB of RAM can be used. If you encounter unexpected\n"); fprintf(stderr, "!! exceptions during import, you should try running in slim\n"); fprintf(stderr, "!! mode using parameter -s.\n"); } while (optind < argc) { /* if input_reader is not forced by -r switch try to auto-detect it by file extension */ if (strcmp("auto", input_reader) == 0) { if (strcasecmp(".pbf",argv[optind]+strlen(argv[optind])-4) == 0) { #ifdef BUILD_READER_PBF streamFile = &streamFilePbf; #else 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"); exit(EXIT_FAILURE); #endif } else if (strcasecmp(".o5m",argv[optind]+strlen(argv[optind])-4) == 0 || strcasecmp(".o5c",argv[optind]+strlen(argv[optind])-4) == 0) { streamFile = &streamFileO5m; } else { streamFile = &streamFileXML2; } } fprintf(stderr, "\nReading in file: %s\n", argv[optind]); time(&start); if (streamFile(argv[optind], sanitize, &osmdata) != 0) exit_nicely(); time(&end); fprintf(stderr, " parse time: %ds\n", (int)(end - start)); optind++; } xmlCleanupParser(); xmlMemoryDump(); if (osmdata.count_node || osmdata.count_way || osmdata.count_rel) { time(&now); end_nodes = osmdata.start_way > 0 ? osmdata.start_way : now; end_way = osmdata.start_rel > 0 ? osmdata.start_rel : now; end_rel = now; fprintf(stderr, "\n"); fprintf(stderr, "Node stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_node, osmdata.max_node, osmdata.count_node > 0 ? (int)(end_nodes - osmdata.start_node) : 0); fprintf(stderr, "Way stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_way, osmdata.max_way, osmdata.count_way > 0 ? (int)(end_way - osmdata.start_way) : 0); fprintf(stderr, "Relation stats: total(%" PRIdOSMID "), max(%" PRIdOSMID ") in %is\n", osmdata.count_rel, osmdata.max_rel, osmdata.count_rel > 0 ? (int)(end_rel - osmdata.start_rel) : 0); } osmdata.out->stop(); free(osmdata.nds); free(osmdata.members); /* free the column pointer buffer */ free(hstore_columns); project_exit(); text_exit(); fprintf(stderr, "\n"); time(&overall_end); fprintf(stderr, "Osm2pgsql took %ds overall\n", (int)(overall_end - overall_start)); return 0; }
/** * Range search returns number of points found, with results in nearest * Normal is optional, but if given will limit results to points in normal direction from co. * Remember to free nearest after use! */ int BLI_kdtree_range_search__normal( KDTree *tree, const float co[3], const float nor[3], KDTreeNearest **r_nearest, float range) { KDTreeNode *root, *node = NULL; KDTreeNode **stack, *defaultstack[KD_STACK_INIT]; KDTreeNearest *foundstack = NULL; float range2 = range * range, dist2; unsigned int totstack, cur = 0, found = 0, totfoundstack = 0; #ifdef DEBUG BLI_assert(tree->is_balanced == true); #endif if (!tree->root) return 0; stack = defaultstack; totstack = KD_STACK_INIT; root = tree->root; if (co[root->d] + range < root->co[root->d]) { if (root->left) stack[cur++] = root->left; } else if (co[root->d] - range > root->co[root->d]) { if (root->right) stack[cur++] = root->right; } else { dist2 = squared_distance(root->co, co, nor); if (dist2 <= range2) add_in_range(&foundstack, found++, &totfoundstack, root->index, dist2, root->co); if (root->left) stack[cur++] = root->left; if (root->right) stack[cur++] = root->right; } while (cur--) { node = stack[cur]; if (co[node->d] + range < node->co[node->d]) { if (node->left) stack[cur++] = node->left; } else if (co[node->d] - range > node->co[node->d]) { if (node->right) stack[cur++] = node->right; } else { dist2 = squared_distance(node->co, co, nor); if (dist2 <= range2) add_in_range(&foundstack, found++, &totfoundstack, node->index, dist2, node->co); if (node->left) stack[cur++] = node->left; if (node->right) stack[cur++] = node->right; } if (UNLIKELY(cur + 3 > totstack)) { stack = realloc_nodes(stack, &totstack, defaultstack != stack); } } if (stack != defaultstack) MEM_freeN(stack); if (found) qsort(foundstack, found, sizeof(KDTreeNearest), range_compare); *r_nearest = foundstack; return (int)found; }
/** * Find n nearest returns number of points found, with results in nearest. * Normal is optional, but if given will limit results to points in normal direction from co. * * \param r_nearest An array of nearest, sized at least \a n. */ int BLI_kdtree_find_nearest_n__normal( KDTree *tree, const float co[3], const float nor[3], KDTreeNearest r_nearest[], unsigned int n) { KDTreeNode *root, *node = NULL; KDTreeNode **stack, *defaultstack[KD_STACK_INIT]; float cur_dist; unsigned int totstack, cur = 0; unsigned int i, found = 0; #ifdef DEBUG BLI_assert(tree->is_balanced == true); #endif if (!tree->root || n == 0) return 0; stack = defaultstack; totstack = KD_STACK_INIT; root = tree->root; cur_dist = squared_distance(root->co, co, nor); add_nearest(r_nearest, &found, n, root->index, cur_dist, root->co); if (co[root->d] < root->co[root->d]) { if (root->right) stack[cur++] = root->right; if (root->left) stack[cur++] = root->left; } else { if (root->left) stack[cur++] = root->left; if (root->right) stack[cur++] = root->right; } while (cur--) { node = stack[cur]; cur_dist = node->co[node->d] - co[node->d]; if (cur_dist < 0.0f) { cur_dist = -cur_dist * cur_dist; if (found < n || -cur_dist < r_nearest[found - 1].dist) { cur_dist = squared_distance(node->co, co, nor); if (found < n || cur_dist < r_nearest[found - 1].dist) add_nearest(r_nearest, &found, n, node->index, cur_dist, node->co); if (node->left) stack[cur++] = node->left; } if (node->right) stack[cur++] = node->right; } else { cur_dist = cur_dist * cur_dist; if (found < n || cur_dist < r_nearest[found - 1].dist) { cur_dist = squared_distance(node->co, co, nor); if (found < n || cur_dist < r_nearest[found - 1].dist) add_nearest(r_nearest, &found, n, node->index, cur_dist, node->co); if (node->right) stack[cur++] = node->right; } if (node->left) stack[cur++] = node->left; } if (UNLIKELY(cur + 3 > totstack)) { stack = realloc_nodes(stack, &totstack, defaultstack != stack); } } for (i = 0; i < found; i++) r_nearest[i].dist = sqrtf(r_nearest[i].dist); if (stack != defaultstack) MEM_freeN(stack); return (int)found; }
/** * Find nearest returns index, and -1 if no node is found. */ int BLI_kdtree_find_nearest( KDTree *tree, const float co[3], KDTreeNearest *r_nearest) { KDTreeNode *root, *node, *min_node; KDTreeNode **stack, *defaultstack[KD_STACK_INIT]; float min_dist, cur_dist; unsigned int totstack, cur = 0; #ifdef DEBUG BLI_assert(tree->is_balanced == true); #endif if (!tree->root) return -1; stack = defaultstack; totstack = KD_STACK_INIT; root = tree->root; min_node = root; min_dist = len_squared_v3v3(root->co, co); if (co[root->d] < root->co[root->d]) { if (root->right) stack[cur++] = root->right; if (root->left) stack[cur++] = root->left; } else { if (root->left) stack[cur++] = root->left; if (root->right) stack[cur++] = root->right; } while (cur--) { node = stack[cur]; cur_dist = node->co[node->d] - co[node->d]; if (cur_dist < 0.0f) { cur_dist = -cur_dist * cur_dist; if (-cur_dist < min_dist) { cur_dist = len_squared_v3v3(node->co, co); if (cur_dist < min_dist) { min_dist = cur_dist; min_node = node; } if (node->left) stack[cur++] = node->left; } if (node->right) stack[cur++] = node->right; } else { cur_dist = cur_dist * cur_dist; if (cur_dist < min_dist) { cur_dist = len_squared_v3v3(node->co, co); if (cur_dist < min_dist) { min_dist = cur_dist; min_node = node; } if (node->right) stack[cur++] = node->right; } if (node->left) stack[cur++] = node->left; } if (UNLIKELY(cur + 3 > totstack)) { stack = realloc_nodes(stack, &totstack, defaultstack != stack); } } if (r_nearest) { r_nearest->index = min_node->index; r_nearest->dist = sqrtf(min_dist); copy_v3_v3(r_nearest->co, min_node->co); } if (stack != defaultstack) MEM_freeN(stack); return min_node->index; }
int main(int argc, char *argv[]) { int append=0; int create=0; int slim=0; int sanitize=0; int long_usage_bool=0; int pass_prompt=0; int projection = PROJ_SPHERE_MERC; int expire_tiles_zoom = -1; int expire_tiles_zoom_min = -1; int enable_hstore = 0; int enable_multi = 0; const char *expire_tiles_filename = "dirty_tiles"; const char *db = "gis"; const char *username=NULL; const char *host=NULL; const char *password=NULL; const char *port = "5432"; const char *tblsindex = "pg_default"; // default TABLESPACE for index const char *conninfo = NULL; const char *prefix = "planet_osm"; const char *style = OSM2PGSQL_DATADIR "/default.style"; const char *temparg; const char *output_backend = "pgsql"; const char *input_reader = "auto"; const char **hstore_columns = NULL; int n_hstore_columns = 0; int cache = 800; struct output_options options; PGconn *sql_conn; int (*streamFile)(char *, int, struct osmdata_t *); printf("osm2pgsql SVN version %s\n\n", VERSION); while (1) { int c, option_index = 0; static struct option long_options[] = { {"append", 0, 0, 'a'}, {"bbox", 1, 0, 'b'}, {"create", 0, 0, 'c'}, {"database", 1, 0, 'd'}, {"latlong", 0, 0, 'l'}, {"verbose", 0, 0, 'v'}, {"slim", 0, 0, 's'}, {"prefix", 1, 0, 'p'}, {"proj", 1, 0, 'E'}, {"merc", 0, 0, 'm'}, {"oldmerc", 0, 0, 'M'}, {"utf8-sanitize", 0, 0, 'u'}, {"cache", 1, 0, 'C'}, {"username", 1, 0, 'U'}, {"password", 0, 0, 'W'}, {"host", 1, 0, 'H'}, {"port", 1, 0, 'P'}, {"tablespace-index", 1, 0, 'i'}, {"help", 0, 0, 'h'}, {"style", 1, 0, 'S'}, {"expire-tiles", 1, 0, 'e'}, {"expire-output", 1, 0, 'o'}, {"output", 1, 0, 'O'}, {"extra-attributes", 0, 0, 'x'}, {"hstore", 0, 0, 'k'}, {"hstore-column", 1, 0, 'z'}, {"multi-geometry", 0, 0, 'G'}, {"input-reader", 1, 0, 'r'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "ab:cd:hlmMp:suvU:WH:P:i:E:C:S:e:o:O:xkGz:r:V", long_options, &option_index); if (c == -1) break; switch (c) { case 'a': append=1; break; case 'b': osmdata.bbox=optarg; break; case 'c': create=1; break; case 'v': verbose=1; break; case 's': slim=1; break; case 'u': sanitize=1; break; case 'l': projection=PROJ_LATLONG; break; case 'm': projection=PROJ_SPHERE_MERC; break; case 'M': projection=PROJ_MERC; break; case 'E': projection=-atoi(optarg); break; case 'p': prefix=optarg; break; case 'd': db=optarg; break; case 'C': cache = atoi(optarg); break; case 'U': username=optarg; break; case 'W': pass_prompt=1; break; case 'H': host=optarg; break; case 'P': port=optarg; break; case 'S': style=optarg; break; case 'i': tblsindex=optarg; break; case 'e': expire_tiles_zoom_min = atoi(optarg); temparg = strchr(optarg, '-'); if (temparg) expire_tiles_zoom = atoi(temparg + 1); if (expire_tiles_zoom < expire_tiles_zoom_min) expire_tiles_zoom = expire_tiles_zoom_min; break; case 'o': expire_tiles_filename=optarg; break; case 'O': output_backend = optarg; break; case 'x': osmdata.extra_attributes=1; break; case 'k': enable_hstore=1; break; case 'z': n_hstore_columns++; hstore_columns = (const char**)realloc(hstore_columns, sizeof(&n_hstore_columns) * n_hstore_columns); hstore_columns[n_hstore_columns-1] = optarg; break; case 'G': enable_multi=1; break; case 'r': input_reader = optarg; break; case 'h': long_usage_bool=1; break; case 'V': exit(EXIT_SUCCESS); case '?': default: short_usage(argv[0]); exit(EXIT_FAILURE); } } if (long_usage_bool) { long_usage(argv[0]); exit(EXIT_SUCCESS); } if (argc == optind) { // No non-switch arguments short_usage(argv[0]); exit(EXIT_FAILURE); } if (append && create) { fprintf(stderr, "Error: --append and --create options can not be used at the same time!\n"); exit(EXIT_FAILURE); } if( cache < 0 ) cache = 0; if (pass_prompt) password = simple_prompt("Password:"******"PGPASS"); } conninfo = build_conninfo(db, username, password, host, port); sql_conn = PQconnectdb(conninfo); if (PQstatus(sql_conn) != CONNECTION_OK) { fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(sql_conn)); exit(EXIT_FAILURE); } PQfinish(sql_conn); text_init(); initList(&osmdata.tags); osmdata.count_node = osmdata.max_node = 0; osmdata.count_way = osmdata.max_way = 0; osmdata.count_rel = osmdata.max_rel = 0; LIBXML_TEST_VERSION project_init(projection); fprintf(stderr, "Using projection SRS %d (%s)\n", project_getprojinfo()->srs, project_getprojinfo()->descr ); if (parse_bbox(&osmdata)) return 1; options.conninfo = conninfo; options.prefix = prefix; options.append = append; options.slim = slim; options.projection = project_getprojinfo()->srs; options.scale = (projection==PROJ_LATLONG)?10000000:100; options.mid = slim ? &mid_pgsql : &mid_ram; options.cache = cache; options.style = style; options.tblsindex = tblsindex; options.expire_tiles_zoom = expire_tiles_zoom; options.expire_tiles_zoom_min = expire_tiles_zoom_min; options.expire_tiles_filename = expire_tiles_filename; options.enable_multi = enable_multi; options.enable_hstore = enable_hstore; options.hstore_columns = hstore_columns; options.n_hstore_columns = n_hstore_columns; if (strcmp("pgsql", output_backend) == 0) { osmdata.out = &out_pgsql; } else if (strcmp("gazetteer", output_backend) == 0) { osmdata.out = &out_gazetteer; } else if (strcmp("null", output_backend) == 0) { osmdata.out = &out_null; } else { fprintf(stderr, "Output backend `%s' not recognised. Should be one of [pgsql, gazetteer, null].\n", output_backend); exit(EXIT_FAILURE); } if (strcmp("auto", input_reader) != 0) { if (strcmp("libxml2", input_reader) == 0) { streamFile = &streamFileXML2; } else if (strcmp("primitive", input_reader) == 0) { streamFile = &streamFilePrimitive; #ifdef BUILD_READER_PBF } else if (strcmp("pbf", input_reader) == 0) { streamFile = &streamFilePbf; #endif } else { fprintf(stderr, "Input parser `%s' not recognised. Should be one of [libxml2, primitive" #ifdef BUILD_READER_PBF ", pbf" #endif "].\n", input_reader); exit(EXIT_FAILURE); } } osmdata.out->start(&options); realloc_nodes(&osmdata); realloc_members(&osmdata); if (sizeof(int*) == 4 && options.slim != 1) { fprintf(stderr, "\n!! You are running this on 32bit system, so at most\n"); fprintf(stderr, "!! 3GB of RAM can be used. If you encounter unexpected\n"); fprintf(stderr, "!! exceptions during import, you should try running in slim\n"); fprintf(stderr, "!! mode using parameter -s.\n"); } while (optind < argc) { /* if input_reader is not forced by -r switch try to auto-detect it by file extension */ if (strcmp("auto", input_reader) == 0) { #ifdef BUILD_READER_PBF if (strcasecmp(".pbf",argv[optind]+strlen(argv[optind])-4) == 0) { streamFile = &streamFilePbf; } else { streamFile = &streamFileXML2; } #else streamFile = &streamFileXML2; #endif } time_t start, end; fprintf(stderr, "\nReading in file: %s\n", argv[optind]); time(&start); if (streamFile(argv[optind], sanitize, &osmdata) != 0) exit_nicely(); time(&end); fprintf(stderr, " parse time: %ds\n", (int)(end - start)); optind++; } xmlCleanupParser(); xmlMemoryDump(); if (osmdata.count_node || osmdata.count_way || osmdata.count_rel) { fprintf(stderr, "\n"); fprintf(stderr, "Node stats: total(%d), max(%d)\n", osmdata.count_node, osmdata.max_node); fprintf(stderr, "Way stats: total(%d), max(%d)\n", osmdata.count_way, osmdata.max_way); fprintf(stderr, "Relation stats: total(%d), max(%d)\n", osmdata.count_rel, osmdata.max_rel); } osmdata.out->stop(); free(osmdata.nds); free(osmdata.members); // free the column pointer buffer free(hstore_columns); project_exit(); text_exit(); fprintf(stderr, "\n"); return 0; }
/** * A version of #BLI_kdtree_find_nearest which runs a callback * to filter out values. * * \param filter_cb: Filter find results, * Return codes: (1: accept, 0: skip, -1: immediate exit). */ int BLI_kdtree_find_nearest_cb( const KDTree *tree, const float co[3], int (*filter_cb)(void *user_data, int index, const float co[3], float dist_sq), void *user_data, KDTreeNearest *r_nearest) { const KDTreeNode *nodes = tree->nodes; const KDTreeNode *min_node = NULL; uint *stack, defaultstack[KD_STACK_INIT]; float min_dist = FLT_MAX, cur_dist; uint totstack, cur = 0; #ifdef DEBUG BLI_assert(tree->is_balanced == true); #endif if (UNLIKELY(tree->root == KD_NODE_UNSET)) return -1; stack = defaultstack; totstack = KD_STACK_INIT; #define NODE_TEST_NEAREST(node) \ { \ const float dist_sq = len_squared_v3v3((node)->co, co); \ if (dist_sq < min_dist) { \ const int result = filter_cb(user_data, (node)->index, (node)->co, dist_sq); \ if (result == 1) { \ min_dist = dist_sq; \ min_node = node; \ } \ else if (result == 0) { \ /* pass */ \ } \ else { \ BLI_assert(result == -1); \ goto finally; \ } \ } \ } ((void)0) stack[cur++] = tree->root; while (cur--) { const KDTreeNode *node = &nodes[stack[cur]]; cur_dist = node->co[node->d] - co[node->d]; if (cur_dist < 0.0f) { cur_dist = -cur_dist * cur_dist; if (-cur_dist < min_dist) { NODE_TEST_NEAREST(node); if (node->left != KD_NODE_UNSET) stack[cur++] = node->left; } if (node->right != KD_NODE_UNSET) stack[cur++] = node->right; } else { cur_dist = cur_dist * cur_dist; if (cur_dist < min_dist) { NODE_TEST_NEAREST(node); if (node->right != KD_NODE_UNSET) stack[cur++] = node->right; } if (node->left != KD_NODE_UNSET) stack[cur++] = node->left; } if (UNLIKELY(cur + 3 > totstack)) { stack = realloc_nodes(stack, &totstack, defaultstack != stack); } } #undef NODE_TEST_NEAREST finally: if (stack != defaultstack) MEM_freeN(stack); if (min_node) { if (r_nearest) { r_nearest->index = min_node->index; r_nearest->dist = sqrtf(min_dist); copy_v3_v3(r_nearest->co, min_node->co); } return min_node->index; } else { return -1; } }