osm2pgsql 0.07: Make UTF8sanitize optional since it is generally no longer required. Add option to output in latlong format

This commit is contained in:
Jon Burgess
2007-09-07 22:22:47 +00:00
parent 67338f9e3b
commit 2fd0b3e35d
11 changed files with 94 additions and 69 deletions

View File

@ -1,5 +1,5 @@
PACKAGE:=osm2pgsql
VERSION:=0.06
VERSION:=0.07
SVN:=$(shell date +%Y%m%d)
CFLAGS += -O2 -Wall -Wextra

View File

@ -85,6 +85,7 @@ struct Interior
static std::vector<Segment> segs;
static std::vector<std::string> wkts;
static std::vector<Interior> interiors;
static std::vector<double> areas;
int is_simple(const char* wkt)
@ -115,10 +116,17 @@ void get_interior(size_t index, double *y, double *x)
*x = interiors[index].x;
*y = interiors[index].y;
}
double get_area(size_t index)
{
return areas[index];
}
void clear_wkts()
{
wkts.clear();
interiors.clear();
areas.clear();
}
size_t build_geometry(int polygon, int osm_id)
@ -175,11 +183,11 @@ size_t build_geometry(int polygon, int osm_id)
{
std::auto_ptr<LinearRing> ring(factory.createLinearRing(pline->getCoordinates()));
std::auto_ptr<Polygon> poly(factory.createPolygon(factory.createLinearRing(pline->getCoordinates()),0));
if (poly->getArea() > ext_area) {
double poly_area = poly->getArea();
if (poly_area > ext_area) {
if (ext_area > 0.0)
interior->push_back(exterior.release());
ext_area = poly->getArea();
ext_area = poly_area;
exterior = ring;
//std::cerr << "Found bigger ring, area(" << ext_area << ") " << writer.write(poly.get()) << std::endl;
} else {
@ -191,16 +199,18 @@ size_t build_geometry(int polygon, int osm_id)
std::string text = writer.write(pline.get());
wkts.push_back(text);
interiors.push_back(Interior(0,0));
++wkt_size;
areas.push_back(0.0);
wkt_size++;
}
}
if (ext_area > 0.0) {
std::auto_ptr<Polygon> poly(factory.createPolygon(exterior.release(), interior.release()));
std::string text = writer.write(poly.get());
//std::cerr << "Result: area(" << poly->getArea() << ") " << writer.write(poly.get()) << std::endl;
wkts.push_back(text);
interiors.push_back(Interior(poly.get()));
//std::cerr << "Result: area(" << poly->getArea() << ") " << writer.write(poly.get()) << std::endl;
areas.push_back(ext_area);
wkt_size++;
}
} else {
@ -210,6 +220,7 @@ size_t build_geometry(int polygon, int osm_id)
std::string text = writer.write(pline.get());
wkts.push_back(text);
interiors.push_back(Interior(0,0));
areas.push_back(0.0);
++wkt_size;
}
}

View File

@ -31,6 +31,7 @@ int is_simple(const char* wkt);
void add_segment(double x0,double y0,double x1, double y1);
char* get_wkt(size_t index);
void get_interior(size_t index, double *y, double *x);
double get_area(size_t index);
size_t build_geometry(int polygon, int osm_id);
void clear_wkts();

12
input.c
View File

@ -151,3 +151,15 @@ int inputClose(void *context)
free(ctx);
return 0;
}
xmlTextReaderPtr inputUTF8(const char *name)
{
void *ctx = inputOpen(name);
if (!ctx) {
fprintf(stderr, "Input reader create failed for: %s\n", name);
return NULL;
}
return xmlReaderForIO(readFile, inputClose, (void *)ctx, NULL, NULL, 0);
}

View File

@ -1,10 +1,11 @@
#ifndef INPUT_H
#define INPUT_H
int inputRead(void *context, char * buffer, int len);
int readFile(void *context, char * buffer, int len);
int inputClose(void *context);
void *inputOpen(const char *name);
char inputGetChar(void *context);
int inputEof(void *context);
xmlTextReaderPtr inputUTF8(const char *name);
#endif

View File

@ -206,7 +206,7 @@ int addItem(struct keyval *head, const char *name, const char *value, int noDupe
item->key = strdup(name);
item->value = strdup(value);
#endif
item->next = head->next;
item->prev = head;
head->next->prev = item;

View File

@ -613,7 +613,8 @@ static void pgsql_end(void)
}
}
static int pgsql_start(const char *db)
#define __unused __attribute__ ((unused))
static int pgsql_start(const char *db, int latlong __unused)
{
char sql[2048];
PGresult *res;

View File

@ -23,10 +23,10 @@
/* Store +-20,000km Mercator co-ordinates as fixed point 32bit number with maximum precision */
/* Scale is chosen such that 40,000 * SCALE < 2^32 */
#define FIXED_POINT
//#define SCALE 10000000
#define SCALE 100
#define DOUBLE_TO_FIX(x) ((x) * SCALE)
#define FIX_TO_DOUBLE(x) (((double)x) / SCALE)
static int scale = 100;
#define DOUBLE_TO_FIX(x) ((x) * scale)
#define FIX_TO_DOUBLE(x) (((double)x) / scale)
struct ramNode {
#ifdef FIXED_POINT
@ -338,8 +338,13 @@ static void ram_end(void)
}
#define __unused __attribute__ ((unused))
static int ram_start(const char * db __unused)
static int ram_start(const char * db __unused, int latlong)
{
// latlong has a range of +-180, mercator +-20000
// The fixed poing scaling needs adjusting accordingly to
// be stored accurately in an int
scale = latlong ? 10000000 : 100;
return 0;
}

View File

@ -10,7 +10,7 @@
#include "keyvals.h"
struct middle_t {
int (*start)(const char *db);
int (*start)(const char *db, int latlong);
void (*stop)(void);
void (*cleanup)(void);
void (*analyze)(void);

View File

@ -43,6 +43,7 @@
#include "sanitizer.h"
#include "reprojection.h"
#include "text-tree.h"
#include "input.h"
static int count_node, max_node;
static int count_segment, max_segment;
@ -62,6 +63,7 @@ static struct keyval tags, segs;
static int osm_id;
int verbose;
int latlong;
static void printStatus(void)
{
@ -165,7 +167,8 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
void EndElement(const xmlChar *name)
{
if (xmlStrEqual(name, BAD_CAST "node")) {
reproject(&node_lat, &node_lon);
if (!latlong)
reproject(&node_lat, &node_lon);
mid->nodes_set(osm_id, node_lat, node_lon, &tags);
resetList(&tags);
} else if (xmlStrEqual(name, BAD_CAST "segment")) {
@ -214,12 +217,14 @@ static void processNode(xmlTextReaderPtr reader) {
xmlFree(name);
}
static int streamFile(char *filename) {
static int streamFile(char *filename, int sanitize) {
xmlTextReaderPtr reader;
int ret = 0;
// reader = xmlNewTextReaderFilename(filename);
reader = sanitizerOpen(filename);
if (sanitize)
reader = sanitizerOpen(filename);
else
reader = inputUTF8(filename);
if (reader != NULL) {
ret = xmlTextReaderRead(reader);
@ -260,16 +265,19 @@ static void usage(const char *arg0)
fprintf(stderr, "\nThis will import the data from the OSM file(s) into a PostgreSQL database\n");
fprintf(stderr, "suitable for use by the Mapnik renderer\n");
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -a --append\tAdd the OSM file into the database without removing\n");
fprintf(stderr, " \texisting data.\n");
fprintf(stderr, " -c --create\tRemove existing data from the database. This is the \n");
fprintf(stderr, " \tdefault if --append is not specified.\n");
fprintf(stderr, " -d --database\tThe name of the PostgreSQL database to connect\n");
fprintf(stderr, " \tto (default: gis).\n");
fprintf(stderr, " -s --slim\t\tStore temporary data in the database. This greatly\n");
fprintf(stderr, " \t\treduces the RAM usage but is much slower.\n");
fprintf(stderr, " -h --help\t\tHelp information.\n");
fprintf(stderr, " -v --verbose\tVerbose output.\n");
fprintf(stderr, " -a|--append\t\tAdd the OSM file into the database without removing\n");
fprintf(stderr, " \t\texisting data.\n");
fprintf(stderr, " -c|--create\t\tRemove existing data from the database. This is the \n");
fprintf(stderr, " \t\tdefault if --append is not specified.\n");
fprintf(stderr, " -d|--database\tThe name of the PostgreSQL database to connect\n");
fprintf(stderr, " \tto (default: gis).\n");
fprintf(stderr, " -l|--latlong\t\tStore data in degrees of latitude & longitude.\n");
fprintf(stderr, " -u|--utf8-sanitize\tRepair bad UTF8 input data (present in planet\n");
fprintf(stderr, " \tdumps prior to August 2007). Adds about 10%% overhead.\n");
fprintf(stderr, " -s|--slim\t\tStore temporary data in the database. This greatly\n");
fprintf(stderr, " \t\treduces the RAM usage but is much slower.\n");
fprintf(stderr, " -h|--help\t\tHelp information.\n");
fprintf(stderr, " -v|--verbose\t\tVerbose output.\n");
fprintf(stderr, "\n");
}
@ -278,6 +286,7 @@ int main(int argc, char *argv[])
int append=0;
int create=0;
int slim=0;
int sanitize=0;
const char *db = "gis";
fprintf(stderr, "osm2pgsql SVN version %s $Rev$ \n\n", VERSION);
@ -293,22 +302,26 @@ int main(int argc, char *argv[])
{"append", 0, 0, 'a'},
{"create", 0, 0, 'c'},
{"database", 1, 0, 'd'},
{"latlong", 0, 0, 'l'},
{"verbose", 0, 0, 'v'},
{"slim", 0, 0, 's'},
{"utf8-sanitize", 0, 0, 'u'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "acd:hsv", long_options, &option_index);
c = getopt_long (argc, argv, "acd:hlsuv", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'a': append=1; break;
case 'c': create=1; break;
case 'v': verbose=1; break;
case 's': slim=1; break;
case 'd': db=optarg; break;
case 'a': append=1; break;
case 'c': create=1; break;
case 'v': verbose=1; break;
case 's': slim=1; break;
case 'u': sanitize=1; break;
case 'l': latlong=1; break;
case 'd': db=optarg; break;
case 'h':
case '?':
@ -338,8 +351,8 @@ int main(int argc, char *argv[])
while (optind < argc) {
fprintf(stderr, "\nReading in file: %s\n", argv[optind]);
mid->start(db);
if (streamFile(argv[optind]) != 0)
mid->start(db, latlong);
if (streamFile(argv[optind], sanitize) != 0)
exit_nicely();
mid->end();
mid->analyze();

View File

@ -74,7 +74,8 @@ static struct {
{"tourism", "text", 1},
{"tunnel", "text", 0},
{"waterway", "text", 0},
{"z_order", "int4", 0}
{"z_order", "int4", 0},
{"way_area", "real", 0}
};
static const unsigned int numTags = sizeof(exportTags) / sizeof(*exportTags);
@ -428,9 +429,16 @@ static int pgsql_out_way(int id, struct keyval *tags, struct osmSegLL *segll, in
for (i=0;i<wkt_size;i++)
{
char *wkt = get_wkt(i);
if (strlen(wkt)) {
/* FIXME: there should be a better way to detect polygons */
if (!strncmp(wkt, "POLYGON", strlen("POLYGON"))) {
double area = get_area(i);
if (area > 0.0) {
char tmp[32];
snprintf(tmp, sizeof(tmp), "%f", area);
addItem(tags, "way_area", tmp, 0);
}
write_wkts(id, tags, wkt, sql_conns[t_poly]);
add_parking_node(id, tags, i);
} else {
@ -511,21 +519,6 @@ static int pgsql_out_start(const char *db, int append)
exit_nicely();
}
PQclear(res);
} else {
if (i == t_poly) {
sql[0] = '\0';
strcat(sql, "ALTER TABLE ");
strcat(sql, tables[i].name);
strcat(sql, " DROP COLUMN way_area;\n");
res = PQexec(sql_conn, sql);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr, "%s failed: %s\n", sql, PQerrorMessage(sql_conn));
PQclear(res);
exit_nicely();
}
PQclear(res);
}
}
sql[0] = '\0';
@ -586,6 +579,10 @@ static void pgsql_out_stop(int append)
strcat(sql, ";\n");
if (!append) {
strcat(sql, "ALTER TABLE ");
strcat(sql, tables[i].name);
strcat(sql, " ALTER COLUMN way SET NOT NULL;\n");
strcat(sql, "CREATE INDEX way_index");
strcat(sql, tmp);
strcat(sql, " ON ");
@ -597,23 +594,7 @@ static void pgsql_out_stop(int append)
strcat(sql, " ON ");
strcat(sql, tables[i].name);
strcat(sql, " (z_order);\n");
strcat(sql, "ALTER TABLE ");
strcat(sql, tables[i].name);
strcat(sql, " ALTER COLUMN way SET NOT NULL;\n");
}
if (i == t_poly) {
strcat(sql, "ALTER TABLE ");
strcat(sql, tables[i].name);
strcat(sql, " ADD COLUMN way_area real;\n");
strcat(sql, "UPDATE ");
strcat(sql, tables[i].name);
strcat(sql, " SET way_area=area(way);\n");
}
strcat(sql, "CLUSTER way_index");
strcat(sql, tmp);
strcat(sql, " ON ");