mirror of
https://github.com/osm2pgsql-dev/osm2pgsql.git
synced 2025-08-19 16:28:16 +00:00
Make changes for 0.5.
This commit is contained in:
@ -36,9 +36,11 @@
|
|||||||
#include <geos/geom/Point.h>
|
#include <geos/geom/Point.h>
|
||||||
#include <geos/io/WKTReader.h>
|
#include <geos/io/WKTReader.h>
|
||||||
#include <geos/io/WKTWriter.h>
|
#include <geos/io/WKTWriter.h>
|
||||||
|
#include <geos/util/GEOSException.h>
|
||||||
#include <geos/opLinemerge.h>
|
#include <geos/opLinemerge.h>
|
||||||
using namespace geos::geom;
|
using namespace geos::geom;
|
||||||
using namespace geos::io;
|
using namespace geos::io;
|
||||||
|
using namespace geos::util;
|
||||||
using namespace geos::operation::linemerge;
|
using namespace geos::operation::linemerge;
|
||||||
#else
|
#else
|
||||||
/* geos-2.2.3 */
|
/* geos-2.2.3 */
|
||||||
@ -50,187 +52,39 @@ using namespace geos;
|
|||||||
|
|
||||||
#include "build_geometry.h"
|
#include "build_geometry.h"
|
||||||
|
|
||||||
typedef std::auto_ptr<Geometry> geom_ptr;
|
using namespace std;
|
||||||
|
|
||||||
struct Segment
|
char *get_wkt(osmNode *nodes, int count, int polygon, double *area) {
|
||||||
{
|
GeometryFactory gf;
|
||||||
Segment(double x0_,double y0_,double x1_,double y1_)
|
|
||||||
:x0(x0_),y0(y0_),x1(x1_),y1(y1_) {}
|
|
||||||
|
|
||||||
double x0;
|
auto_ptr<CoordinateSequence> coords(
|
||||||
double y0;
|
gf.getCoordinateSequenceFactory()->create(0, 2));
|
||||||
double x1;
|
for (int i = 0; i < count; i++) {
|
||||||
double y1;
|
Coordinate c;
|
||||||
};
|
c.x = nodes[i].lon;
|
||||||
|
c.y = nodes[i].lat;
|
||||||
|
coords->add(c, i);
|
||||||
|
}
|
||||||
|
|
||||||
struct Interior
|
auto_ptr<Geometry> geom;
|
||||||
{
|
if (polygon) {
|
||||||
Interior(double x_, double y_)
|
if (coords->getSize() < 4 ||
|
||||||
: x(x_), y(y_) {}
|
!coords->getAt(coords->getSize() - 1).equals2D(coords->getAt(0))) {
|
||||||
|
return 0;
|
||||||
Interior(Geometry *geom) {
|
|
||||||
try {
|
|
||||||
std::auto_ptr<Point> pt(geom->getInteriorPoint());
|
|
||||||
x = pt->getX();
|
|
||||||
y = pt->getY();
|
|
||||||
} catch (...) {
|
|
||||||
// This happens on some unusual polygons, we'll ignore them for now
|
|
||||||
//std::cerr << std::endl << "Exception finding interior point" << std::endl;
|
|
||||||
x=y=0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
GeometryFactory factory;
|
|
||||||
WKTReader reader(&factory);
|
|
||||||
geom_ptr geom(reader.read(wkt));
|
|
||||||
if (geom->isSimple()) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_segment(double x0,double y0,double x1,double y1)
|
|
||||||
{
|
|
||||||
segs.push_back(Segment(x0,y0,x1,y1));
|
|
||||||
}
|
|
||||||
|
|
||||||
char * get_wkt(size_t index)
|
|
||||||
{
|
|
||||||
// return wkts[index].c_str();
|
|
||||||
char *result;
|
|
||||||
result = (char*) std::malloc( wkts[index].length() + 1);
|
|
||||||
std::strcpy(result, wkts[index].c_str() );
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
size_t wkt_size = 0;
|
|
||||||
GeometryFactory factory;
|
|
||||||
geom_ptr segment(0);
|
|
||||||
std::auto_ptr<std::vector<Geometry*> > lines(new std::vector<Geometry*>);
|
|
||||||
std::vector<Segment>::const_iterator pos=segs.begin();
|
|
||||||
std::vector<Segment>::const_iterator end=segs.end();
|
|
||||||
bool first=true;
|
|
||||||
try {
|
|
||||||
while (pos != end)
|
|
||||||
{
|
|
||||||
if (pos->x0 != pos->x1 || pos->y0 != pos->y1)
|
|
||||||
{
|
|
||||||
std::auto_ptr<CoordinateSequence> coords(factory.getCoordinateSequenceFactory()->create(0,2));
|
|
||||||
coords->add(Coordinate(pos->x0,pos->y0));
|
|
||||||
coords->add(Coordinate(pos->x1,pos->y1));
|
|
||||||
geom_ptr linestring(factory.createLineString(coords.release()));
|
|
||||||
if (first)
|
|
||||||
{
|
|
||||||
segment = linestring;
|
|
||||||
first=false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lines->push_back(linestring.release());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
segs.clear();
|
|
||||||
|
|
||||||
if (segment.get())
|
|
||||||
{
|
|
||||||
geom_ptr mline (factory.createMultiLineString(lines.release()));
|
|
||||||
geom_ptr noded (segment->Union(mline.get()));
|
|
||||||
LineMerger merger;
|
|
||||||
merger.add(noded.get());
|
|
||||||
std::auto_ptr<std::vector<LineString *> > merged(merger.getMergedLineStrings());
|
|
||||||
WKTWriter writer;
|
|
||||||
|
|
||||||
if (polygon)
|
|
||||||
{
|
|
||||||
std::auto_ptr<LinearRing> exterior;
|
|
||||||
std::auto_ptr<std::vector<Geometry*> > interior(new std::vector<Geometry*>);
|
|
||||||
double ext_area = 0.0;
|
|
||||||
for (unsigned i=0 ;i < merged->size(); ++i)
|
|
||||||
{
|
|
||||||
std::auto_ptr<LineString> pline ((*merged ) [i]);
|
|
||||||
if (pline->getNumPoints() > 3 && pline->isClosed())
|
|
||||||
{
|
|
||||||
std::auto_ptr<LinearRing> ring(factory.createLinearRing(pline->getCoordinates()));
|
|
||||||
std::auto_ptr<Polygon> poly(factory.createPolygon(factory.createLinearRing(pline->getCoordinates()),0));
|
|
||||||
double poly_area = poly->getArea();
|
|
||||||
if (poly_area > ext_area) {
|
|
||||||
if (ext_area > 0.0)
|
|
||||||
interior->push_back(exterior.release());
|
|
||||||
ext_area = poly_area;
|
|
||||||
exterior = ring;
|
|
||||||
//std::cerr << "Found bigger ring, area(" << ext_area << ") " << writer.write(poly.get()) << std::endl;
|
|
||||||
} else {
|
|
||||||
interior->push_back(ring.release());
|
|
||||||
//std::cerr << "Found inner ring, area(" << poly->getArea() << ") " << writer.write(poly.get()) << std::endl;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//std::cerr << "polygon(" << osm_id << ") is no good: points(" << pline->getNumPoints() << "), closed(" << pline->isClosed() << "). " << writer.write(pline.get()) << std::endl;
|
|
||||||
std::string text = writer.write(pline.get());
|
|
||||||
wkts.push_back(text);
|
|
||||||
interiors.push_back(Interior(0,0));
|
|
||||||
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()));
|
|
||||||
areas.push_back(ext_area);
|
|
||||||
wkt_size++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (unsigned i=0 ;i < merged->size(); ++i)
|
|
||||||
{
|
|
||||||
std::auto_ptr<LineString> pline ((*merged ) [i]);
|
|
||||||
std::string text = writer.write(pline.get());
|
|
||||||
wkts.push_back(text);
|
|
||||||
interiors.push_back(Interior(0,0));
|
|
||||||
areas.push_back(0.0);
|
|
||||||
++wkt_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (...)
|
auto_ptr<LinearRing> shell(gf.createLinearRing(coords.release()));
|
||||||
{
|
geom = auto_ptr<Geometry>(gf.createPolygon(shell.release(),
|
||||||
std::cerr << std::endl << "excepton caught processing way id=" << osm_id << std::endl;
|
new vector<Geometry *>));
|
||||||
wkt_size = 0;
|
*area = geom->getArea();
|
||||||
|
} else {
|
||||||
|
if (coords->getSize() < 2) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return wkt_size;
|
geom = auto_ptr<Geometry>(gf.createLineString(coords.release()));
|
||||||
}
|
*area = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WKTWriter wktw;
|
||||||
|
string wkt = wktw.write(geom.get());
|
||||||
|
return strdup(wkt.c_str());
|
||||||
|
}
|
||||||
|
@ -27,13 +27,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int is_simple(const char* wkt);
|
#include "osmtypes.h"
|
||||||
void add_segment(double x0,double y0,double x1, double y1);
|
|
||||||
char* get_wkt(size_t index);
|
char *get_wkt(struct osmNode *, int count, int polygon, double *area);
|
||||||
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();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
177
middle-pgsql.c
177
middle-pgsql.c
@ -24,7 +24,7 @@
|
|||||||
static char conninfo[256];
|
static char conninfo[256];
|
||||||
|
|
||||||
enum table_id {
|
enum table_id {
|
||||||
t_node, t_segment, t_node_tag, t_way_tag, t_way_seg
|
t_node, t_node_tag, t_way_tag, t_way_nd
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
struct table_desc {
|
struct table_desc {
|
||||||
@ -50,17 +50,6 @@ static struct table_desc tables [] = {
|
|||||||
analyze: "ANALYZE nodes;\n",
|
analyze: "ANALYZE nodes;\n",
|
||||||
stop: "COMMIT;\n"
|
stop: "COMMIT;\n"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
//table: t_segment,
|
|
||||||
name: "segments",
|
|
||||||
start: "BEGIN;\n",
|
|
||||||
create: "CREATE TABLE segments (\"id\" int4 PRIMARY KEY,\"from\" int4,\"to\" int4);\n",
|
|
||||||
prepare: "PREPARE insert_segment (int4, int4, int4) AS INSERT INTO segments VALUES ($1,$2,$3);\n"
|
|
||||||
"PREPARE get_segment (int4) AS SELECT \"from\",\"to\" FROM segments WHERE \"id\" = $1 LIMIT 1;\n",
|
|
||||||
copy: "COPY segments FROM STDIN;\n",
|
|
||||||
analyze: "ANALYZE segments;\n",
|
|
||||||
stop: "COMMIT;\n"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
//table: t_node_tag,
|
//table: t_node_tag,
|
||||||
name: "node_tag",
|
name: "node_tag",
|
||||||
@ -88,15 +77,15 @@ static struct table_desc tables [] = {
|
|||||||
stop: "COMMIT;\n"
|
stop: "COMMIT;\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//table: t_way_seg,
|
//table: t_way_nd,
|
||||||
name: "way_seg",
|
name: "way_nd",
|
||||||
start: "BEGIN;\n",
|
start: "BEGIN;\n",
|
||||||
create: "CREATE TABLE way_seg (\"id\" int4 NOT NULL, \"seg_id\" int4);\n"
|
create: "CREATE TABLE way_nd (\"id\" int4 NOT NULL, \"nd_id\" int4);\n"
|
||||||
"CREATE INDEX way_seg_idx ON way_seg (\"id\");\n",
|
"CREATE INDEX way_nd_idx ON way_nd (\"id\");\n",
|
||||||
prepare: "PREPARE insert_way_seg (int4, int4) AS INSERT INTO way_seg VALUES ($1,$2);\n"
|
prepare: "PREPARE insert_way_nd (int4, int4) AS INSERT INTO way_nd VALUES ($1,$2);\n"
|
||||||
"PREPARE get_way_seg (int4) AS SELECT \"seg_id\" FROM way_seg WHERE \"id\" = $1;\n",
|
"PREPARE get_way_nd (int4) AS SELECT \"nd_id\" FROM way_nd WHERE \"id\" = $1;\n",
|
||||||
copy: "COPY way_seg FROM STDIN;\n",
|
copy: "COPY way_nd FROM STDIN;\n",
|
||||||
analyze: "ANALYZE way_seg;\n",
|
analyze: "ANALYZE way_nd;\n",
|
||||||
stop: "COMMIT;\n"
|
stop: "COMMIT;\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -268,59 +257,13 @@ static int pgsql_nodes_get(struct osmNode *out, int id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pgsql_segments_set(int id, int from, int to, struct keyval *tags)
|
static void psql_add_way_nd(int way_id, int nd_id)
|
||||||
{
|
{
|
||||||
PGconn *sql_conn = sql_conns[t_segment];
|
PGconn *sql_conn = sql_conns[t_way_nd];
|
||||||
char sql[128];
|
char sql[128];
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
sprintf(sql, "%d\t%d\t%d\n", id, from, to);
|
sprintf(sql, "%d\t%d\n", way_id, nd_id);
|
||||||
r = PQputCopyData(sql_conn, sql, strlen(sql));
|
|
||||||
if (r != 1) {
|
|
||||||
fprintf(stderr, "%s - bad result %d, line %s\n", __FUNCTION__, r, sql);
|
|
||||||
exit_nicely();
|
|
||||||
}
|
|
||||||
resetList(tags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pgsql_segments_get(struct osmSegment *out, int id)
|
|
||||||
{
|
|
||||||
PGresult *res;
|
|
||||||
char tmp[16];
|
|
||||||
char const *paramValues[1];
|
|
||||||
PGconn *sql_conn = sql_conns[t_segment];
|
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), "%d", id);
|
|
||||||
paramValues[0] = tmp;
|
|
||||||
|
|
||||||
res = PQexecPrepared(sql_conn, "get_segment", 1, paramValues, NULL, NULL, 0);
|
|
||||||
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
|
|
||||||
fprintf(stderr, "get_segment failed: %s(%d)\n", PQerrorMessage(sql_conn), PQresultStatus(res));
|
|
||||||
PQclear(res);
|
|
||||||
exit_nicely();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PQntuples(res) != 1) {
|
|
||||||
PQclear(res);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
out->from = strtol(PQgetvalue(res, 0, 0), NULL, 10);
|
|
||||||
out->to = strtol(PQgetvalue(res, 0, 1), NULL, 10);
|
|
||||||
PQclear(res);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void psql_add_way_seg(int way_id, int seg_id)
|
|
||||||
{
|
|
||||||
PGconn *sql_conn = sql_conns[t_way_seg];
|
|
||||||
char sql[128];
|
|
||||||
int r;
|
|
||||||
|
|
||||||
sprintf(sql, "%d\t%d\n", way_id, seg_id);
|
|
||||||
r = PQputCopyData(sql_conn, sql, strlen(sql));
|
r = PQputCopyData(sql_conn, sql, strlen(sql));
|
||||||
if (r != 1) {
|
if (r != 1) {
|
||||||
fprintf(stderr, "%s - bad result %d, line %s\n", __FUNCTION__, r, sql);
|
fprintf(stderr, "%s - bad result %d, line %s\n", __FUNCTION__, r, sql);
|
||||||
@ -329,14 +272,14 @@ static void psql_add_way_seg(int way_id, int seg_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int pgsql_ways_set(int way_id, struct keyval *segs, struct keyval *tags)
|
static int pgsql_ways_set(int way_id, struct keyval *nds, struct keyval *tags)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
struct keyval *p;
|
struct keyval *p;
|
||||||
|
|
||||||
while((p = popItem(segs)) != NULL) {
|
while((p = popItem(nds)) != NULL) {
|
||||||
int seg_id = strtol(p->value, NULL, 10);
|
int nd_id = strtol(p->value, NULL, 10);
|
||||||
psql_add_way_seg(way_id, seg_id);
|
psql_add_way_nd(way_id, nd_id);
|
||||||
freeItem(p);
|
freeItem(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,9 +289,9 @@ static int pgsql_ways_set(int way_id, struct keyval *segs, struct keyval *tags)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// FIXME: Performance hack - output ways directly. Doesn't work in COPY model
|
// FIXME: Performance hack - output ways directly. Doesn't work in COPY model
|
||||||
out_pgsql.way(&mid_pgsql, way_id, tags, segs);
|
out_pgsql.way(&mid_pgsql, way_id, tags, nds);
|
||||||
resetList(tags);
|
resetList(tags);
|
||||||
resetList(segs);
|
resetList(nds);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -412,49 +355,6 @@ static void pgsql_iterate_nodes(int (*callback)(int id, struct keyval *tags, dou
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static struct osmSegLL *getSegLL(struct keyval *segs, int *segCount)
|
|
||||||
{
|
|
||||||
struct keyval *p;
|
|
||||||
struct osmSegment segment;
|
|
||||||
struct osmNode node;
|
|
||||||
int id;
|
|
||||||
int count = 0;
|
|
||||||
struct osmSegLL *segll = malloc(countList(segs) * sizeof(struct osmSegLL));
|
|
||||||
|
|
||||||
if (!segll) {
|
|
||||||
resetList(segs);
|
|
||||||
*segCount = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((p = popItem(segs)) != NULL)
|
|
||||||
{
|
|
||||||
id = strtol(p->value, NULL, 10);
|
|
||||||
freeItem(p);
|
|
||||||
|
|
||||||
if (pgsql_segments_get(&segment, id))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (pgsql_nodes_get(&node, segment.from))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
segll[count].lon0 = node.lon;
|
|
||||||
segll[count].lat0 = node.lat;
|
|
||||||
|
|
||||||
if (pgsql_nodes_get(&node, segment.to))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
segll[count].lon1 = node.lon;
|
|
||||||
segll[count].lat1 = node.lat;
|
|
||||||
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
*segCount = count;
|
|
||||||
return segll;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void getTags(int id, struct keyval *tags)
|
void getTags(int id, struct keyval *tags)
|
||||||
{
|
{
|
||||||
PGconn *sql_conn_tags = sql_conns[t_way_tag];
|
PGconn *sql_conn_tags = sql_conns[t_way_tag];
|
||||||
@ -482,14 +382,14 @@ void getTags(int id, struct keyval *tags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void pgsql_iterate_ways(int (*callback)(int id, struct keyval *tags, struct osmSegLL *segll, int count))
|
static void pgsql_iterate_ways(int (*callback)(int id, struct keyval *tags, struct osmNode *nodes, int count))
|
||||||
{
|
{
|
||||||
char sql[2048];
|
char sql[2048];
|
||||||
PGresult *res_ways, *res_nodes;
|
PGresult *res_ways, *res_nodes;
|
||||||
int i, j, count = 0;
|
int i, j, count = 0;
|
||||||
struct keyval tags;
|
struct keyval tags;
|
||||||
struct osmSegLL *segll;
|
struct osmNode *nodes;
|
||||||
PGconn *sql_conn_segs = sql_conns[t_way_seg];
|
PGconn *sql_conn_nds = sql_conns[t_way_nd];
|
||||||
|
|
||||||
initList(&tags);
|
initList(&tags);
|
||||||
|
|
||||||
@ -504,9 +404,9 @@ gis=> select w.id,s.id,nf.lat,nf.lon,nt.lat,nt.lon from way_seg as w,nodes as nf
|
|||||||
3186577 | 10872310 | 51.721258 | -0.359137 | 51.720979 | -0.360532
|
3186577 | 10872310 | 51.721258 | -0.359137 | 51.720979 | -0.360532
|
||||||
*/
|
*/
|
||||||
|
|
||||||
res_ways = PQexec(sql_conn_segs, "SELECT id from way_seg GROUP BY id");
|
res_ways = PQexec(sql_conn_nds, "SELECT id from way_nd GROUP BY id");
|
||||||
if (PQresultStatus(res_ways) != PGRES_TUPLES_OK) {
|
if (PQresultStatus(res_ways) != PGRES_TUPLES_OK) {
|
||||||
fprintf(stderr, "%s(%d) failed: %s\n", __FUNCTION__, __LINE__, PQerrorMessage(sql_conn_segs));
|
fprintf(stderr, "%s(%d) failed: %s\n", __FUNCTION__, __LINE__, PQerrorMessage(sql_conn_nds));
|
||||||
PQclear(res_ways);
|
PQclear(res_ways);
|
||||||
exit_nicely();
|
exit_nicely();
|
||||||
}
|
}
|
||||||
@ -514,36 +414,33 @@ gis=> select w.id,s.id,nf.lat,nf.lon,nt.lat,nt.lon from way_seg as w,nodes as nf
|
|||||||
//fprintf(stderr, "\nIterating ways\n");
|
//fprintf(stderr, "\nIterating ways\n");
|
||||||
for (i = 0; i < PQntuples(res_ways); i++) {
|
for (i = 0; i < PQntuples(res_ways); i++) {
|
||||||
int id = strtol(PQgetvalue(res_ways, i, 0), NULL, 10);
|
int id = strtol(PQgetvalue(res_ways, i, 0), NULL, 10);
|
||||||
int segCount;
|
int ndCount;
|
||||||
|
|
||||||
if (count++ %1000 == 0)
|
if (count++ %1000 == 0)
|
||||||
fprintf(stderr, "\rprocessing way (%dk)", count/1000);
|
fprintf(stderr, "\rprocessing way (%dk)", count/1000);
|
||||||
|
|
||||||
getTags(id, &tags);
|
getTags(id, &tags);
|
||||||
|
|
||||||
sprintf(sql,"SELECT nf.lat,nf.lon,nt.lat,nt.lon "
|
sprintf(sql,"SELECT n.lat, n.lon FROM way_nd AS w, nodes AS n "
|
||||||
"FROM way_seg AS w,nodes AS nf, nodes AS nt, segments AS s "
|
"WHERE w.nd_id = n.id AND w.id=%d", id);
|
||||||
"WHERE w.seg_id=s.id AND nf.id=s.from AND nt.id=s.to AND w.id=%d", id);
|
|
||||||
|
|
||||||
res_nodes = PQexec(sql_conn_segs, sql);
|
res_nodes = PQexec(sql_conn_nds, sql);
|
||||||
if (PQresultStatus(res_nodes) != PGRES_TUPLES_OK) {
|
if (PQresultStatus(res_nodes) != PGRES_TUPLES_OK) {
|
||||||
fprintf(stderr, "%s(%d) failed: %s\n", __FUNCTION__, __LINE__, PQerrorMessage(sql_conn_segs));
|
fprintf(stderr, "%s(%d) failed: %s\n", __FUNCTION__, __LINE__, PQerrorMessage(sql_conn_nds));
|
||||||
PQclear(res_nodes);
|
PQclear(res_nodes);
|
||||||
exit_nicely();
|
exit_nicely();
|
||||||
}
|
}
|
||||||
|
|
||||||
segCount = PQntuples(res_nodes);
|
ndCount = PQntuples(res_nodes);
|
||||||
segll = malloc(segCount * sizeof(struct osmSegLL));
|
nodes = malloc(ndCount * sizeof(struct osmNode));
|
||||||
|
|
||||||
if (segll) {
|
if (nodes) {
|
||||||
for (j=0; j<segCount; j++) {
|
for (j=0; j<ndCount; j++) {
|
||||||
segll[j].lat0 = strtod(PQgetvalue(res_nodes, j, 0), NULL);
|
nodes[j].lat = strtod(PQgetvalue(res_nodes, j, 0), NULL);
|
||||||
segll[j].lon0 = strtod(PQgetvalue(res_nodes, j, 1), NULL);
|
nodes[j].lon = strtod(PQgetvalue(res_nodes, j, 1), NULL);
|
||||||
segll[j].lat1 = strtod(PQgetvalue(res_nodes, j, 2), NULL);
|
|
||||||
segll[j].lon1 = strtod(PQgetvalue(res_nodes, j, 3), NULL);
|
|
||||||
}
|
}
|
||||||
callback(id, &tags, segll, segCount);
|
callback(id, &tags, nodes, ndCount);
|
||||||
free(segll);
|
free(nodes);
|
||||||
}
|
}
|
||||||
PQclear(res_nodes);
|
PQclear(res_nodes);
|
||||||
resetList(&tags);
|
resetList(&tags);
|
||||||
@ -725,8 +622,6 @@ struct middle_t mid_pgsql = {
|
|||||||
cleanup: pgsql_cleanup,
|
cleanup: pgsql_cleanup,
|
||||||
analyze: pgsql_analyze,
|
analyze: pgsql_analyze,
|
||||||
end: pgsql_end,
|
end: pgsql_end,
|
||||||
segments_set: pgsql_segments_set,
|
|
||||||
segments_get: pgsql_segments_get,
|
|
||||||
nodes_set: pgsql_nodes_set,
|
nodes_set: pgsql_nodes_set,
|
||||||
nodes_get: pgsql_nodes_get,
|
nodes_get: pgsql_nodes_get,
|
||||||
ways_set: pgsql_ways_set,
|
ways_set: pgsql_ways_set,
|
||||||
|
163
middle-ram.c
163
middle-ram.c
@ -38,14 +38,9 @@ struct ramNode {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ramSegment {
|
|
||||||
int from;
|
|
||||||
int to;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ramWay {
|
struct ramWay {
|
||||||
struct keyval *tags;
|
struct keyval *tags;
|
||||||
int *segids;
|
int *ndids;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Object storage now uses 2 levels of storage arrays.
|
/* Object storage now uses 2 levels of storage arrays.
|
||||||
@ -67,17 +62,16 @@ struct ramWay {
|
|||||||
#define NUM_BLOCKS (1 << (32 - BLOCK_SHIFT))
|
#define NUM_BLOCKS (1 << (32 - BLOCK_SHIFT))
|
||||||
|
|
||||||
static struct ramNode *nodes[NUM_BLOCKS];
|
static struct ramNode *nodes[NUM_BLOCKS];
|
||||||
static struct ramSegment *segments[NUM_BLOCKS];
|
|
||||||
static struct ramWay *ways[NUM_BLOCKS];
|
static struct ramWay *ways[NUM_BLOCKS];
|
||||||
|
|
||||||
static int node_blocks, segment_blocks;
|
static int node_blocks;
|
||||||
#ifdef USE_CLEAN
|
#ifdef USE_CLEAN
|
||||||
static int way_blocks;
|
static int way_blocks;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int way_out_count;
|
static int way_out_count;
|
||||||
|
|
||||||
static struct osmSegLL *getSegLL(int *segids, int *segCount);
|
static struct osmNode *getNodes(int *ndids, int *ndCount);
|
||||||
|
|
||||||
static inline int id2block(int id)
|
static inline int id2block(int id)
|
||||||
{
|
{
|
||||||
@ -151,53 +145,16 @@ static int ram_nodes_get(struct osmNode *out, int id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ram_segments_set(int id, int from, int to, struct keyval *tags)
|
static int ram_ways_set(int id, struct keyval *nds, struct keyval *tags)
|
||||||
{
|
|
||||||
int block = id2block(id);
|
|
||||||
int offset = id2offset(id);
|
|
||||||
|
|
||||||
if (!segments[block]) {
|
|
||||||
segments[block] = calloc(PER_BLOCK, sizeof(struct ramSegment));
|
|
||||||
if (!segments[block]) {
|
|
||||||
fprintf(stderr, "Error allocating segments\n");
|
|
||||||
exit_nicely();
|
|
||||||
}
|
|
||||||
segment_blocks++;
|
|
||||||
//fprintf(stderr, "\tsegments(%zuMb)\n", segment_blocks * sizeof(struct ramSegment) * PER_BLOCK / 1000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
segments[block][offset].from = from;
|
|
||||||
segments[block][offset].to = to;
|
|
||||||
resetList(tags);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ram_segments_get(struct osmSegment *out, int id)
|
|
||||||
{
|
|
||||||
int block = id2block(id);
|
|
||||||
int offset = id2offset(id);
|
|
||||||
|
|
||||||
if (!segments[block])
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (!segments[block][offset].from && !segments[block][offset].to)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
out->from = segments[block][offset].from;
|
|
||||||
out->to = segments[block][offset].to;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ram_ways_set(int id, struct keyval *segs, struct keyval *tags)
|
|
||||||
{
|
{
|
||||||
struct keyval *p;
|
struct keyval *p;
|
||||||
int *segids;
|
int *ndids;
|
||||||
int segCount, i;
|
int ndCount, i;
|
||||||
#ifdef USE_CLEAN
|
#ifdef USE_CLEAN
|
||||||
int block = id2block(id);
|
int block = id2block(id);
|
||||||
int offset = id2offset(id);
|
int offset = id2offset(id);
|
||||||
#else
|
#else
|
||||||
struct osmSegLL *segll;
|
struct osmNode *nodes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CLEAN
|
#ifdef USE_CLEAN
|
||||||
@ -211,33 +168,37 @@ static int ram_ways_set(int id, struct keyval *segs, struct keyval *tags)
|
|||||||
//fprintf(stderr, "\tways(%zuMb)\n", way_blocks * sizeof(struct ramWay) * PER_BLOCK / 1000000);
|
//fprintf(stderr, "\tways(%zuMb)\n", way_blocks * sizeof(struct ramWay) * PER_BLOCK / 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ways[block][offset].segids) {
|
ndCount = countList(nds);
|
||||||
free(ways[block][offset].segids);
|
if (!ndCount)
|
||||||
ways[block][offset].segids = NULL;
|
return 1;
|
||||||
|
|
||||||
|
if (ways[block][offset].ndids) {
|
||||||
|
free(ways[block][offset].ndids);
|
||||||
|
ways[block][offset].ndids = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
segCount = countList(segs);
|
ndCount = countList(nds);
|
||||||
if (!segCount)
|
if (!ndCount)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
segids = malloc(sizeof(int) * (segCount+1));
|
ndids = malloc(sizeof(int) * (ndCount+1));
|
||||||
if (!segids) {
|
if (!ndids) {
|
||||||
fprintf(stderr, "%s malloc failed\n", __FUNCTION__);
|
fprintf(stderr, "%s malloc failed\n", __FUNCTION__);
|
||||||
exit_nicely();
|
exit_nicely();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_CLEAN
|
#ifdef USE_CLEAN
|
||||||
ways[block][offset].segids = segids;
|
ways[block][offset].ndids = ndids;
|
||||||
#endif
|
#endif
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((p = popItem(segs)) != NULL) {
|
while ((p = popItem(nds)) != NULL) {
|
||||||
int seg_id = strtol(p->value, NULL, 10);
|
int nd_id = strtol(p->value, NULL, 10);
|
||||||
freeItem(p);
|
freeItem(p);
|
||||||
if (seg_id) /* id = 0 is used as list terminator */
|
if (nd_id) /* id = 0 is used as list terminator */
|
||||||
segids[i++] = seg_id;
|
ndids[i++] = nd_id;
|
||||||
}
|
}
|
||||||
segids[i] = 0;
|
ndids[i] = 0;
|
||||||
#ifdef USE_CLEAN
|
#ifdef USE_CLEAN
|
||||||
if (!ways[block][offset].tags) {
|
if (!ways[block][offset].tags) {
|
||||||
p = malloc(sizeof(struct keyval));
|
p = malloc(sizeof(struct keyval));
|
||||||
@ -254,65 +215,51 @@ static int ram_ways_set(int id, struct keyval *segs, struct keyval *tags)
|
|||||||
while ((p = popItem(tags)) != NULL)
|
while ((p = popItem(tags)) != NULL)
|
||||||
pushItem(ways[block][offset].tags, p);
|
pushItem(ways[block][offset].tags, p);
|
||||||
#else
|
#else
|
||||||
segll = getSegLL(segids, &segCount);
|
nodes = getNodes(ndids, &ndCount);
|
||||||
free(segids);
|
free(ndids);
|
||||||
|
|
||||||
if (segll) {
|
if (nodes) {
|
||||||
out_pgsql.way(id, tags, segll, segCount);
|
out_pgsql.way(id, tags, nodes, ndCount);
|
||||||
free(segll);
|
free(nodes);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct osmSegLL *getSegLL(int *segids, int *segCount)
|
static struct osmNode *getNodes(int *ndids, int *ndCount)
|
||||||
{
|
{
|
||||||
struct osmSegment segment;
|
|
||||||
struct osmNode node;
|
|
||||||
int id;
|
int id;
|
||||||
int i, count = 0;
|
int i, count = 0;
|
||||||
struct osmSegLL *segll;
|
struct osmNode *nodes;
|
||||||
|
|
||||||
while(segids[count])
|
while(ndids[count])
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
segll = malloc(count * sizeof(struct osmSegLL));
|
nodes = malloc(count * sizeof(struct osmNode));
|
||||||
|
|
||||||
if (!segll) {
|
if (!nodes) {
|
||||||
*segCount = 0;
|
*ndCount = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((id = segids[i++]) != 0)
|
while ((id = ndids[i++]) != 0)
|
||||||
{
|
{
|
||||||
if (ram_segments_get(&segment, id))
|
if (ram_nodes_get(&nodes[count], id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ram_nodes_get(&node, segment.from))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
segll[count].lon0 = node.lon;
|
|
||||||
segll[count].lat0 = node.lat;
|
|
||||||
|
|
||||||
if (ram_nodes_get(&node, segment.to))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
segll[count].lon1 = node.lon;
|
|
||||||
segll[count].lat1 = node.lat;
|
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
*segCount = count;
|
*ndCount = count;
|
||||||
return segll;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ram_iterate_ways(int (*callback)(int id, struct keyval *tags, struct osmSegLL *segll, int count))
|
static void ram_iterate_ways(int (*callback)(int id, struct keyval *tags, struct osmNode *nodes, int count))
|
||||||
{
|
{
|
||||||
int block, offset, segCount = 0;
|
int block, offset, ndCount = 0;
|
||||||
struct osmSegLL *segll;
|
struct osmNode *nodes;
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
for(block=NUM_BLOCKS-1; block>=0; block--) {
|
for(block=NUM_BLOCKS-1; block>=0; block--) {
|
||||||
@ -320,17 +267,17 @@ static void ram_iterate_ways(int (*callback)(int id, struct keyval *tags, struct
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (offset=0; offset < PER_BLOCK; offset++) {
|
for (offset=0; offset < PER_BLOCK; offset++) {
|
||||||
if (ways[block][offset].segids) {
|
if (ways[block][offset].ndids) {
|
||||||
way_out_count++;
|
way_out_count++;
|
||||||
if (way_out_count % 1000 == 0)
|
if (way_out_count % 1000 == 0)
|
||||||
fprintf(stderr, "\rWriting way(%uk)", way_out_count/1000);
|
fprintf(stderr, "\rWriting way(%uk)", way_out_count/1000);
|
||||||
|
|
||||||
segll = getSegLL(ways[block][offset].segids, &segCount);
|
nodes = getNodes(ways[block][offset].ndids, &ndCount);
|
||||||
|
|
||||||
if (segll) {
|
if (nodes) {
|
||||||
int id = block2id(block, offset);
|
int id = block2id(block, offset);
|
||||||
callback(id, ways[block][offset].tags, segll, segCount);
|
callback(id, ways[block][offset].tags, nodes, ndCount);
|
||||||
free(segll);
|
free(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ways[block][offset].tags) {
|
if (ways[block][offset].tags) {
|
||||||
@ -338,9 +285,9 @@ static void ram_iterate_ways(int (*callback)(int id, struct keyval *tags, struct
|
|||||||
free(ways[block][offset].tags);
|
free(ways[block][offset].tags);
|
||||||
ways[block][offset].tags = NULL;
|
ways[block][offset].tags = NULL;
|
||||||
}
|
}
|
||||||
if (ways[block][offset].segids) {
|
if (ways[block][offset].ndids) {
|
||||||
free(ways[block][offset].segids);
|
free(ways[block][offset].ndids);
|
||||||
ways[block][offset].segids = NULL;
|
ways[block][offset].ndids = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,18 +325,14 @@ static void ram_stop(void)
|
|||||||
free(nodes[i]);
|
free(nodes[i]);
|
||||||
nodes[i] = NULL;
|
nodes[i] = NULL;
|
||||||
}
|
}
|
||||||
if (segments[i]) {
|
|
||||||
free(segments[i]);
|
|
||||||
segments[i] = NULL;
|
|
||||||
}
|
|
||||||
if (ways[i]) {
|
if (ways[i]) {
|
||||||
for (j=0; j<PER_BLOCK; j++) {
|
for (j=0; j<PER_BLOCK; j++) {
|
||||||
if (ways[i][j].tags) {
|
if (ways[i][j].tags) {
|
||||||
resetList(ways[i][j].tags);
|
resetList(ways[i][j].tags);
|
||||||
free(ways[i][j].tags);
|
free(ways[i][j].tags);
|
||||||
}
|
}
|
||||||
if (ways[i][j].segids)
|
if (ways[i][j].ndids)
|
||||||
free(ways[i][j].segids);
|
free(ways[i][j].ndids);
|
||||||
}
|
}
|
||||||
free(ways[i]);
|
free(ways[i]);
|
||||||
ways[i] = NULL;
|
ways[i] = NULL;
|
||||||
@ -403,8 +346,6 @@ struct middle_t mid_ram = {
|
|||||||
end: ram_end,
|
end: ram_end,
|
||||||
cleanup: ram_stop,
|
cleanup: ram_stop,
|
||||||
analyze: ram_analyze,
|
analyze: ram_analyze,
|
||||||
segments_set: ram_segments_set,
|
|
||||||
segments_get: ram_segments_get,
|
|
||||||
nodes_set: ram_nodes_set,
|
nodes_set: ram_nodes_set,
|
||||||
nodes_get: ram_nodes_get,
|
nodes_get: ram_nodes_get,
|
||||||
ways_set: ram_ways_set,
|
ways_set: ram_ways_set,
|
||||||
|
6
middle.h
6
middle.h
@ -1,7 +1,7 @@
|
|||||||
/* Common middle layer interface */
|
/* Common middle layer interface */
|
||||||
|
|
||||||
/* Each middle layer data store must provide methods for
|
/* Each middle layer data store must provide methods for
|
||||||
* storing and retrieving node, segment and way data.
|
* storing and retrieving node and way data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MIDDLE_H
|
#ifndef MIDDLE_H
|
||||||
@ -15,14 +15,12 @@ struct middle_t {
|
|||||||
void (*cleanup)(void);
|
void (*cleanup)(void);
|
||||||
void (*analyze)(void);
|
void (*analyze)(void);
|
||||||
void (*end)(void);
|
void (*end)(void);
|
||||||
int (*segments_set)(int id, int from, int to, struct keyval *tags);
|
|
||||||
int (*segments_get)(struct osmSegment *out, int id);
|
|
||||||
int (*nodes_set)(int id, double lat, double lon, struct keyval *tags);
|
int (*nodes_set)(int id, double lat, double lon, struct keyval *tags);
|
||||||
int (*nodes_get)(struct osmNode *out, int id);
|
int (*nodes_get)(struct osmNode *out, int id);
|
||||||
int (*ways_set)(int id, struct keyval *segs, struct keyval *tags);
|
int (*ways_set)(int id, struct keyval *segs, struct keyval *tags);
|
||||||
int *(*ways_get)(int id);
|
int *(*ways_get)(int id);
|
||||||
void (*iterate_nodes)(int (*callback)(int id, struct keyval *tags, double node_lat, double node_lon));
|
void (*iterate_nodes)(int (*callback)(int id, struct keyval *tags, double node_lat, double node_lon));
|
||||||
void (*iterate_ways)(int (*callback)(int id, struct keyval *tags, struct osmSegLL *segll, int count));
|
void (*iterate_ways)(int (*callback)(int id, struct keyval *tags, struct osmNode *nodes, int count));
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
116
osm2pgsql.c
116
osm2pgsql.c
@ -46,20 +46,18 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
static int count_node, max_node;
|
static int count_node, max_node;
|
||||||
static int count_segment, max_segment;
|
|
||||||
static int count_way, max_way;
|
static int count_way, max_way;
|
||||||
static int count_way_seg;
|
static int count_rel, max_rel;
|
||||||
|
|
||||||
struct middle_t *mid;
|
struct middle_t *mid;
|
||||||
struct output_t *out;
|
struct output_t *out;
|
||||||
|
|
||||||
/* Since {node,segment,way} elements are not nested we can guarantee the
|
/* Since {node,way} elements are not nested we can guarantee the
|
||||||
values in an end tag must match those of the corresponding
|
values in an end tag must match those of the corresponding
|
||||||
start tag and can therefore be cached.
|
start tag and can therefore be cached.
|
||||||
*/
|
*/
|
||||||
static double node_lon, node_lat;
|
static double node_lon, node_lat;
|
||||||
static int seg_to, seg_from;
|
static struct keyval tags, nds, members;
|
||||||
static struct keyval tags, segs;
|
|
||||||
static int osm_id;
|
static int osm_id;
|
||||||
|
|
||||||
int verbose;
|
int verbose;
|
||||||
@ -67,14 +65,15 @@ int latlong;
|
|||||||
|
|
||||||
static void printStatus(void)
|
static void printStatus(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "\rProcessing: Node(%dk) Segment(%dk) Way(%dk)",
|
fprintf(stderr, "\rProcessing: Node(%dk) Way(%dk) Relation(%dk)",
|
||||||
count_node/1000, count_segment/1000, count_way/1000);
|
count_node/1000, count_way/1000, count_rel/1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||||
{
|
{
|
||||||
xmlChar *xid, *xlat, *xlon, *xfrom, *xto, *xk, *xv;
|
xmlChar *xid, *xlat, *xlon, *xk, *xv, *xrole, *xtype;
|
||||||
|
char membtmp[32];
|
||||||
char *k;
|
char *k;
|
||||||
|
|
||||||
if (xmlStrEqual(name, BAD_CAST "node")) {
|
if (xmlStrEqual(name, BAD_CAST "node")) {
|
||||||
@ -97,25 +96,6 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
|||||||
xmlFree(xid);
|
xmlFree(xid);
|
||||||
xmlFree(xlon);
|
xmlFree(xlon);
|
||||||
xmlFree(xlat);
|
xmlFree(xlat);
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "segment")) {
|
|
||||||
xid = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
|
||||||
xfrom = xmlTextReaderGetAttribute(reader, BAD_CAST "from");
|
|
||||||
xto = xmlTextReaderGetAttribute(reader, BAD_CAST "to");
|
|
||||||
assert(xid); assert(xfrom); assert(xto);
|
|
||||||
osm_id = strtol((char *)xid, NULL, 10);
|
|
||||||
seg_from = strtol((char *)xfrom, NULL, 10);
|
|
||||||
seg_to = strtol((char *)xto, NULL, 10);
|
|
||||||
|
|
||||||
if (osm_id > max_segment)
|
|
||||||
max_segment = osm_id;
|
|
||||||
|
|
||||||
count_segment++;
|
|
||||||
if (count_segment%10000 == 0)
|
|
||||||
printStatus();
|
|
||||||
|
|
||||||
xmlFree(xid);
|
|
||||||
xmlFree(xfrom);
|
|
||||||
xmlFree(xto);
|
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "tag")) {
|
} else if (xmlStrEqual(name, BAD_CAST "tag")) {
|
||||||
xk = xmlTextReaderGetAttribute(reader, BAD_CAST "k");
|
xk = xmlTextReaderGetAttribute(reader, BAD_CAST "k");
|
||||||
assert(xk);
|
assert(xk);
|
||||||
@ -147,14 +127,61 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
|||||||
printStatus();
|
printStatus();
|
||||||
|
|
||||||
xmlFree(xid);
|
xmlFree(xid);
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "seg")) {
|
} else if (xmlStrEqual(name, BAD_CAST "nd")) {
|
||||||
xid = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
xid = xmlTextReaderGetAttribute(reader, BAD_CAST "ref");
|
||||||
assert(xid);
|
assert(xid);
|
||||||
|
|
||||||
if (addItem(&segs, "id", (char *)xid, 1))
|
addItem(&nds, "id", (char *)xid, 0);
|
||||||
count_way_seg++;
|
|
||||||
|
|
||||||
xmlFree(xid);
|
xmlFree(xid);
|
||||||
|
} else if (xmlStrEqual(name, BAD_CAST "relation")) {
|
||||||
|
xid = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
||||||
|
assert(xid);
|
||||||
|
osm_id = strtol((char *)xid, NULL, 10);
|
||||||
|
|
||||||
|
if (osm_id > max_rel)
|
||||||
|
max_rel = osm_id;
|
||||||
|
|
||||||
|
count_rel++;
|
||||||
|
if (count_rel%1000 == 0)
|
||||||
|
printStatus();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* The value we insert into the members keyval will be of the form [nwr]$id,
|
||||||
|
* that way we don't have another data structure and we can switch on the
|
||||||
|
* first char to figure out the type of the member. */
|
||||||
|
|
||||||
|
if (xmlStrEqual(xtype, BAD_CAST "node")) {
|
||||||
|
membtmp[0] = 'n';
|
||||||
|
} else if (xmlStrEqual(xtype, BAD_CAST "way")) {
|
||||||
|
membtmp[0] = 'w';
|
||||||
|
} else if (xmlStrEqual(xtype, BAD_CAST "relation")) {
|
||||||
|
membtmp[0] = 'r';
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: Unknown member type: %s\n",
|
||||||
|
__FUNCTION__, xtype);
|
||||||
|
membtmp[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (membtmp[0]) {
|
||||||
|
strncpy(membtmp + 1, (char *) xid, sizeof(membtmp) - 1);
|
||||||
|
assert(membtmp[sizeof(membtmp) - 1] == 0);
|
||||||
|
addItem(&members, (char *) xrole, membtmp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlFree(xid);
|
||||||
|
xmlFree(xrole);
|
||||||
|
xmlFree(xtype);
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "osm")) {
|
} else if (xmlStrEqual(name, BAD_CAST "osm")) {
|
||||||
/* ignore */
|
/* ignore */
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "bound")) {
|
} else if (xmlStrEqual(name, BAD_CAST "bound")) {
|
||||||
@ -171,17 +198,20 @@ void EndElement(const xmlChar *name)
|
|||||||
reproject(&node_lat, &node_lon);
|
reproject(&node_lat, &node_lon);
|
||||||
mid->nodes_set(osm_id, node_lat, node_lon, &tags);
|
mid->nodes_set(osm_id, node_lat, node_lon, &tags);
|
||||||
resetList(&tags);
|
resetList(&tags);
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "segment")) {
|
|
||||||
mid->segments_set(osm_id, seg_from, seg_to, &tags);
|
|
||||||
resetList(&tags);
|
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "way")) {
|
} else if (xmlStrEqual(name, BAD_CAST "way")) {
|
||||||
mid->ways_set(osm_id, &segs, &tags);
|
mid->ways_set(osm_id, &nds, &tags);
|
||||||
resetList(&tags);
|
resetList(&tags);
|
||||||
resetList(&segs);
|
resetList(&nds);
|
||||||
|
} else if (xmlStrEqual(name, BAD_CAST "relation")) {
|
||||||
|
/* mid->relations_set(osm_id, &members, &tags); */
|
||||||
|
resetList(&tags);
|
||||||
|
resetList(&members);
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "tag")) {
|
} else if (xmlStrEqual(name, BAD_CAST "tag")) {
|
||||||
/* ignore */
|
/* ignore */
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "seg")) {
|
} else if (xmlStrEqual(name, BAD_CAST "nd")) {
|
||||||
/* ignore */
|
/* ignore */
|
||||||
|
} else if (xmlStrEqual(name, BAD_CAST "member")) {
|
||||||
|
/* ignore */
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "osm")) {
|
} else if (xmlStrEqual(name, BAD_CAST "osm")) {
|
||||||
printStatus();
|
printStatus();
|
||||||
} else if (xmlStrEqual(name, BAD_CAST "bound")) {
|
} else if (xmlStrEqual(name, BAD_CAST "bound")) {
|
||||||
@ -338,7 +368,12 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
text_init();
|
text_init();
|
||||||
initList(&tags);
|
initList(&tags);
|
||||||
initList(&segs);
|
initList(&nds);
|
||||||
|
initList(&members);
|
||||||
|
|
||||||
|
count_node = max_node = 0;
|
||||||
|
count_way = max_way = 0;
|
||||||
|
count_rel = max_rel = 0;
|
||||||
|
|
||||||
LIBXML_TEST_VERSION
|
LIBXML_TEST_VERSION
|
||||||
|
|
||||||
@ -366,12 +401,11 @@ int main(int argc, char *argv[])
|
|||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
xmlMemoryDump();
|
xmlMemoryDump();
|
||||||
|
|
||||||
if (count_node || count_segment || count_way) {
|
if (count_node || count_way || count_rel) {
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "Node stats: total(%d), max(%d)\n", count_node, max_node);
|
fprintf(stderr, "Node stats: total(%d), max(%d)\n", count_node, max_node);
|
||||||
fprintf(stderr, "Segment stats: total(%d), max(%d)\n", count_segment, max_segment);
|
|
||||||
fprintf(stderr, "Way stats: total(%d), max(%d)\n", count_way, max_way);
|
fprintf(stderr, "Way stats: total(%d), max(%d)\n", count_way, max_way);
|
||||||
//fprintf(stderr, "Way stats: duplicate segments in ways %d\n", count_way_seg);
|
fprintf(stderr, "Relation stats: total(%d), max(%d)\n", count_rel, max_rel);
|
||||||
}
|
}
|
||||||
//fprintf(stderr, "\n\nEnding data import\n");
|
//fprintf(stderr, "\n\nEnding data import\n");
|
||||||
//out->process(mid);
|
//out->process(mid);
|
||||||
|
12
osmtypes.h
12
osmtypes.h
@ -9,18 +9,6 @@ struct osmNode {
|
|||||||
double lat;
|
double lat;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct osmSegment {
|
|
||||||
int from;
|
|
||||||
int to;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct osmSegLL {
|
|
||||||
double lon0;
|
|
||||||
double lat0;
|
|
||||||
double lon1;
|
|
||||||
double lat1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* exit_nicely - called to cleanup after fatal error */
|
/* exit_nicely - called to cleanup after fatal error */
|
||||||
void exit_nicely(void);
|
void exit_nicely(void);
|
||||||
|
|
||||||
|
@ -322,23 +322,6 @@ static int pgsql_out_node(int id, struct keyval *tags, double node_lat, double n
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static size_t WKT(struct osmSegLL *segll, int count, int polygon, int osm_id)
|
|
||||||
{
|
|
||||||
double x0, y0, x1, y1;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0; i<count; i++) {
|
|
||||||
x0 = segll[i].lon0;
|
|
||||||
y0 = segll[i].lat0;
|
|
||||||
x1 = segll[i].lon1;
|
|
||||||
y1 = segll[i].lat1;
|
|
||||||
add_segment(x0,y0,x1,y1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return build_geometry(polygon, osm_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void write_wkts(int id, struct keyval *tags, const char *wkt, PGconn *sql_conn)
|
static void write_wkts(int id, struct keyval *tags, const char *wkt, PGconn *sql_conn)
|
||||||
{
|
{
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
@ -364,7 +347,7 @@ static void write_wkts(int id, struct keyval *tags, const char *wkt, PGconn *sql
|
|||||||
sql_out(sql_conn, "\n", 1);
|
sql_out(sql_conn, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_parking_node(int id, struct keyval *tags, size_t index)
|
void add_parking_node(int id, struct keyval *tags)
|
||||||
{
|
{
|
||||||
// insert into planet_osm_point(osm_id,name,amenity,way) select osm_id,name,amenity,centroid(way) from planet_osm_polygon where amenity='parking';
|
// insert into planet_osm_point(osm_id,name,amenity,way) select osm_id,name,amenity,centroid(way) from planet_osm_polygon where amenity='parking';
|
||||||
const char *amenity = getItem(tags, "amenity");
|
const char *amenity = getItem(tags, "amenity");
|
||||||
@ -380,8 +363,6 @@ void add_parking_node(int id, struct keyval *tags, size_t index)
|
|||||||
if (name)
|
if (name)
|
||||||
addItem(&nodeTags, "name", name, 0);
|
addItem(&nodeTags, "name", name, 0);
|
||||||
|
|
||||||
get_interior(index, &node_lat, &node_lon);
|
|
||||||
|
|
||||||
//fprintf(stderr, "Parking node: %s\t%f,%f\n", name ? name : "no_name", node_lat, node_lon);
|
//fprintf(stderr, "Parking node: %s\t%f,%f\n", name ? name : "no_name", node_lat, node_lon);
|
||||||
|
|
||||||
pgsql_out_node(id, &nodeTags, node_lat, node_lon);
|
pgsql_out_node(id, &nodeTags, node_lat, node_lon);
|
||||||
@ -397,13 +378,14 @@ E4C1421D5BF24D06053E7DF4940
|
|||||||
212696 Oswald Road \N \N \N \N \N \N minor \N \N \N \N \N \N \N 0102000020E610000004000000467D923B6C22D5BFA359D93EE4DF4940B3976DA7AD11D5BF84BBB376DBDF4940997FF44D9A06D5BF4223D8B8FEDF49404D158C4AEA04D
|
212696 Oswald Road \N \N \N \N \N \N minor \N \N \N \N \N \N \N 0102000020E610000004000000467D923B6C22D5BFA359D93EE4DF4940B3976DA7AD11D5BF84BBB376DBDF4940997FF44D9A06D5BF4223D8B8FEDF49404D158C4AEA04D
|
||||||
5BF5BB39597FCDF4940
|
5BF5BB39597FCDF4940
|
||||||
*/
|
*/
|
||||||
static int pgsql_out_way(int id, struct keyval *tags, struct osmSegLL *segll, int count)
|
static int pgsql_out_way(int id, struct keyval *tags, struct osmNode *nodes, int count)
|
||||||
{
|
{
|
||||||
const char *v;
|
const char *v;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
size_t wkt_size;
|
|
||||||
int polygon = 0, export = 0;
|
int polygon = 0, export = 0;
|
||||||
int roads = 0;
|
int roads = 0;
|
||||||
|
char *wkt;
|
||||||
|
double area;
|
||||||
|
|
||||||
for (i=0; i < numTags; i++) {
|
for (i=0; i < numTags; i++) {
|
||||||
if ((v = getItem(tags, exportTags[i].name))) {
|
if ((v = getItem(tags, exportTags[i].name))) {
|
||||||
@ -424,33 +406,25 @@ static int pgsql_out_way(int id, struct keyval *tags, struct osmSegLL *segll, in
|
|||||||
|
|
||||||
fix_motorway_shields(tags);
|
fix_motorway_shields(tags);
|
||||||
|
|
||||||
wkt_size = WKT(segll, count, polygon, id);
|
wkt = get_wkt(nodes, count, polygon, &area);
|
||||||
|
if (wkt && strlen(wkt)) {
|
||||||
for (i=0;i<wkt_size;i++)
|
/* FIXME: there should be a better way to detect polygons */
|
||||||
{
|
if (!strncmp(wkt, "POLYGON", strlen("POLYGON"))) {
|
||||||
char *wkt = get_wkt(i);
|
if (area > 0.0) {
|
||||||
|
char tmp[32];
|
||||||
if (strlen(wkt)) {
|
snprintf(tmp, sizeof(tmp), "%f", area);
|
||||||
/* FIXME: there should be a better way to detect polygons */
|
addItem(tags, "way_area", tmp, 0);
|
||||||
if (!strncmp(wkt, "POLYGON", strlen("POLYGON"))) {
|
}
|
||||||
double area = get_area(i);
|
write_wkts(id, tags, wkt, sql_conns[t_poly]);
|
||||||
if (area > 0.0) {
|
add_parking_node(id, tags);
|
||||||
char tmp[32];
|
} else {
|
||||||
snprintf(tmp, sizeof(tmp), "%f", area);
|
write_wkts(id, tags, wkt, sql_conns[t_line]);
|
||||||
addItem(tags, "way_area", tmp, 0);
|
if (roads)
|
||||||
}
|
write_wkts(id, tags, wkt, sql_conns[t_roads]);
|
||||||
write_wkts(id, tags, wkt, sql_conns[t_poly]);
|
|
||||||
add_parking_node(id, tags, i);
|
|
||||||
} else {
|
|
||||||
write_wkts(id, tags, wkt, sql_conns[t_line]);
|
|
||||||
if (roads)
|
|
||||||
write_wkts(id, tags, wkt, sql_conns[t_roads]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free(wkt);
|
|
||||||
}
|
}
|
||||||
|
free(wkt);
|
||||||
|
|
||||||
clear_wkts();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
output.h
2
output.h
@ -19,7 +19,7 @@ struct output_t {
|
|||||||
void (*cleanup)(void);
|
void (*cleanup)(void);
|
||||||
void (*process)(struct middle_t *mid);
|
void (*process)(struct middle_t *mid);
|
||||||
int (*node)(int id, struct keyval *tags, double node_lat, double node_lon);
|
int (*node)(int id, struct keyval *tags, double node_lat, double node_lon);
|
||||||
int (*way)(int id, struct keyval *tags, struct osmSegLL *segll, int count);
|
int (*way)(int id, struct keyval *tags, struct osmNode *nodes, int count);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user