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/io/WKTReader.h>
|
||||
#include <geos/io/WKTWriter.h>
|
||||
#include <geos/util/GEOSException.h>
|
||||
#include <geos/opLinemerge.h>
|
||||
using namespace geos::geom;
|
||||
using namespace geos::io;
|
||||
using namespace geos::util;
|
||||
using namespace geos::operation::linemerge;
|
||||
#else
|
||||
/* geos-2.2.3 */
|
||||
@ -50,187 +52,39 @@ using namespace geos;
|
||||
|
||||
#include "build_geometry.h"
|
||||
|
||||
typedef std::auto_ptr<Geometry> geom_ptr;
|
||||
using namespace std;
|
||||
|
||||
struct Segment
|
||||
{
|
||||
Segment(double x0_,double y0_,double x1_,double y1_)
|
||||
:x0(x0_),y0(y0_),x1(x1_),y1(y1_) {}
|
||||
char *get_wkt(osmNode *nodes, int count, int polygon, double *area) {
|
||||
GeometryFactory gf;
|
||||
|
||||
double x0;
|
||||
double y0;
|
||||
double x1;
|
||||
double y1;
|
||||
};
|
||||
auto_ptr<CoordinateSequence> coords(
|
||||
gf.getCoordinateSequenceFactory()->create(0, 2));
|
||||
for (int i = 0; i < count; i++) {
|
||||
Coordinate c;
|
||||
c.x = nodes[i].lon;
|
||||
c.y = nodes[i].lat;
|
||||
coords->add(c, i);
|
||||
}
|
||||
|
||||
struct Interior
|
||||
{
|
||||
Interior(double x_, double y_)
|
||||
: x(x_), y(y_) {}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto_ptr<Geometry> geom;
|
||||
if (polygon) {
|
||||
if (coords->getSize() < 4 ||
|
||||
!coords->getAt(coords->getSize() - 1).equals2D(coords->getAt(0))) {
|
||||
return 0;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cerr << std::endl << "excepton caught processing way id=" << osm_id << std::endl;
|
||||
wkt_size = 0;
|
||||
auto_ptr<LinearRing> shell(gf.createLinearRing(coords.release()));
|
||||
geom = auto_ptr<Geometry>(gf.createPolygon(shell.release(),
|
||||
new vector<Geometry *>));
|
||||
*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" {
|
||||
#endif
|
||||
|
||||
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();
|
||||
#include "osmtypes.h"
|
||||
|
||||
char *get_wkt(struct osmNode *, int count, int polygon, double *area);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
177
middle-pgsql.c
177
middle-pgsql.c
@ -24,7 +24,7 @@
|
||||
static char conninfo[256];
|
||||
|
||||
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 {
|
||||
@ -50,17 +50,6 @@ static struct table_desc tables [] = {
|
||||
analyze: "ANALYZE nodes;\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,
|
||||
name: "node_tag",
|
||||
@ -88,15 +77,15 @@ static struct table_desc tables [] = {
|
||||
stop: "COMMIT;\n"
|
||||
},
|
||||
{
|
||||
//table: t_way_seg,
|
||||
name: "way_seg",
|
||||
//table: t_way_nd,
|
||||
name: "way_nd",
|
||||
start: "BEGIN;\n",
|
||||
create: "CREATE TABLE way_seg (\"id\" int4 NOT NULL, \"seg_id\" int4);\n"
|
||||
"CREATE INDEX way_seg_idx ON way_seg (\"id\");\n",
|
||||
prepare: "PREPARE insert_way_seg (int4, int4) AS INSERT INTO way_seg VALUES ($1,$2);\n"
|
||||
"PREPARE get_way_seg (int4) AS SELECT \"seg_id\" FROM way_seg WHERE \"id\" = $1;\n",
|
||||
copy: "COPY way_seg FROM STDIN;\n",
|
||||
analyze: "ANALYZE way_seg;\n",
|
||||
create: "CREATE TABLE way_nd (\"id\" int4 NOT NULL, \"nd_id\" int4);\n"
|
||||
"CREATE INDEX way_nd_idx ON way_nd (\"id\");\n",
|
||||
prepare: "PREPARE insert_way_nd (int4, int4) AS INSERT INTO way_nd VALUES ($1,$2);\n"
|
||||
"PREPARE get_way_nd (int4) AS SELECT \"nd_id\" FROM way_nd WHERE \"id\" = $1;\n",
|
||||
copy: "COPY way_nd FROM STDIN;\n",
|
||||
analyze: "ANALYZE way_nd;\n",
|
||||
stop: "COMMIT;\n"
|
||||
}
|
||||
};
|
||||
@ -268,59 +257,13 @@ static int pgsql_nodes_get(struct osmNode *out, int id)
|
||||
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];
|
||||
int r;
|
||||
|
||||
sprintf(sql, "%d\t%d\t%d\n", id, from, to);
|
||||
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);
|
||||
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);
|
||||
@ -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
|
||||
struct keyval *p;
|
||||
|
||||
while((p = popItem(segs)) != NULL) {
|
||||
int seg_id = strtol(p->value, NULL, 10);
|
||||
psql_add_way_seg(way_id, seg_id);
|
||||
while((p = popItem(nds)) != NULL) {
|
||||
int nd_id = strtol(p->value, NULL, 10);
|
||||
psql_add_way_nd(way_id, nd_id);
|
||||
freeItem(p);
|
||||
}
|
||||
|
||||
@ -346,9 +289,9 @@ static int pgsql_ways_set(int way_id, struct keyval *segs, struct keyval *tags)
|
||||
}
|
||||
#else
|
||||
// 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(segs);
|
||||
resetList(nds);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -412,49 +355,6 @@ static void pgsql_iterate_nodes(int (*callback)(int id, struct keyval *tags, dou
|
||||
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)
|
||||
{
|
||||
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];
|
||||
PGresult *res_ways, *res_nodes;
|
||||
int i, j, count = 0;
|
||||
struct keyval tags;
|
||||
struct osmSegLL *segll;
|
||||
PGconn *sql_conn_segs = sql_conns[t_way_seg];
|
||||
struct osmNode *nodes;
|
||||
PGconn *sql_conn_nds = sql_conns[t_way_nd];
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
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) {
|
||||
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);
|
||||
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");
|
||||
for (i = 0; i < PQntuples(res_ways); i++) {
|
||||
int id = strtol(PQgetvalue(res_ways, i, 0), NULL, 10);
|
||||
int segCount;
|
||||
int ndCount;
|
||||
|
||||
if (count++ %1000 == 0)
|
||||
fprintf(stderr, "\rprocessing way (%dk)", count/1000);
|
||||
|
||||
getTags(id, &tags);
|
||||
|
||||
sprintf(sql,"SELECT nf.lat,nf.lon,nt.lat,nt.lon "
|
||||
"FROM way_seg AS w,nodes AS nf, nodes AS nt, segments AS s "
|
||||
"WHERE w.seg_id=s.id AND nf.id=s.from AND nt.id=s.to AND w.id=%d", id);
|
||||
sprintf(sql,"SELECT n.lat, n.lon FROM way_nd AS w, nodes AS n "
|
||||
"WHERE w.nd_id = n.id 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) {
|
||||
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);
|
||||
exit_nicely();
|
||||
}
|
||||
|
||||
segCount = PQntuples(res_nodes);
|
||||
segll = malloc(segCount * sizeof(struct osmSegLL));
|
||||
ndCount = PQntuples(res_nodes);
|
||||
nodes = malloc(ndCount * sizeof(struct osmNode));
|
||||
|
||||
if (segll) {
|
||||
for (j=0; j<segCount; j++) {
|
||||
segll[j].lat0 = strtod(PQgetvalue(res_nodes, j, 0), NULL);
|
||||
segll[j].lon0 = 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);
|
||||
if (nodes) {
|
||||
for (j=0; j<ndCount; j++) {
|
||||
nodes[j].lat = strtod(PQgetvalue(res_nodes, j, 0), NULL);
|
||||
nodes[j].lon = strtod(PQgetvalue(res_nodes, j, 1), NULL);
|
||||
}
|
||||
callback(id, &tags, segll, segCount);
|
||||
free(segll);
|
||||
callback(id, &tags, nodes, ndCount);
|
||||
free(nodes);
|
||||
}
|
||||
PQclear(res_nodes);
|
||||
resetList(&tags);
|
||||
@ -725,8 +622,6 @@ struct middle_t mid_pgsql = {
|
||||
cleanup: pgsql_cleanup,
|
||||
analyze: pgsql_analyze,
|
||||
end: pgsql_end,
|
||||
segments_set: pgsql_segments_set,
|
||||
segments_get: pgsql_segments_get,
|
||||
nodes_set: pgsql_nodes_set,
|
||||
nodes_get: pgsql_nodes_get,
|
||||
ways_set: pgsql_ways_set,
|
||||
|
163
middle-ram.c
163
middle-ram.c
@ -38,14 +38,9 @@ struct ramNode {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ramSegment {
|
||||
int from;
|
||||
int to;
|
||||
};
|
||||
|
||||
struct ramWay {
|
||||
struct keyval *tags;
|
||||
int *segids;
|
||||
int *ndids;
|
||||
};
|
||||
|
||||
/* Object storage now uses 2 levels of storage arrays.
|
||||
@ -67,17 +62,16 @@ struct ramWay {
|
||||
#define NUM_BLOCKS (1 << (32 - BLOCK_SHIFT))
|
||||
|
||||
static struct ramNode *nodes[NUM_BLOCKS];
|
||||
static struct ramSegment *segments[NUM_BLOCKS];
|
||||
static struct ramWay *ways[NUM_BLOCKS];
|
||||
|
||||
static int node_blocks, segment_blocks;
|
||||
static int node_blocks;
|
||||
#ifdef USE_CLEAN
|
||||
static int way_blocks;
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
@ -151,53 +145,16 @@ static int ram_nodes_get(struct osmNode *out, int id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ram_segments_set(int id, int from, int to, 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)
|
||||
static int ram_ways_set(int id, struct keyval *nds, struct keyval *tags)
|
||||
{
|
||||
struct keyval *p;
|
||||
int *segids;
|
||||
int segCount, i;
|
||||
int *ndids;
|
||||
int ndCount, i;
|
||||
#ifdef USE_CLEAN
|
||||
int block = id2block(id);
|
||||
int offset = id2offset(id);
|
||||
#else
|
||||
struct osmSegLL *segll;
|
||||
struct osmNode *nodes;
|
||||
#endif
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
if (ways[block][offset].segids) {
|
||||
free(ways[block][offset].segids);
|
||||
ways[block][offset].segids = NULL;
|
||||
ndCount = countList(nds);
|
||||
if (!ndCount)
|
||||
return 1;
|
||||
|
||||
if (ways[block][offset].ndids) {
|
||||
free(ways[block][offset].ndids);
|
||||
ways[block][offset].ndids = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
segCount = countList(segs);
|
||||
if (!segCount)
|
||||
ndCount = countList(nds);
|
||||
if (!ndCount)
|
||||
return 1;
|
||||
|
||||
segids = malloc(sizeof(int) * (segCount+1));
|
||||
if (!segids) {
|
||||
ndids = malloc(sizeof(int) * (ndCount+1));
|
||||
if (!ndids) {
|
||||
fprintf(stderr, "%s malloc failed\n", __FUNCTION__);
|
||||
exit_nicely();
|
||||
}
|
||||
|
||||
#ifdef USE_CLEAN
|
||||
ways[block][offset].segids = segids;
|
||||
ways[block][offset].ndids = ndids;
|
||||
#endif
|
||||
i = 0;
|
||||
while ((p = popItem(segs)) != NULL) {
|
||||
int seg_id = strtol(p->value, NULL, 10);
|
||||
while ((p = popItem(nds)) != NULL) {
|
||||
int nd_id = strtol(p->value, NULL, 10);
|
||||
freeItem(p);
|
||||
if (seg_id) /* id = 0 is used as list terminator */
|
||||
segids[i++] = seg_id;
|
||||
if (nd_id) /* id = 0 is used as list terminator */
|
||||
ndids[i++] = nd_id;
|
||||
}
|
||||
segids[i] = 0;
|
||||
ndids[i] = 0;
|
||||
#ifdef USE_CLEAN
|
||||
if (!ways[block][offset].tags) {
|
||||
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)
|
||||
pushItem(ways[block][offset].tags, p);
|
||||
#else
|
||||
segll = getSegLL(segids, &segCount);
|
||||
free(segids);
|
||||
nodes = getNodes(ndids, &ndCount);
|
||||
free(ndids);
|
||||
|
||||
if (segll) {
|
||||
out_pgsql.way(id, tags, segll, segCount);
|
||||
free(segll);
|
||||
if (nodes) {
|
||||
out_pgsql.way(id, tags, nodes, ndCount);
|
||||
free(nodes);
|
||||
}
|
||||
#endif
|
||||
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 i, count = 0;
|
||||
struct osmSegLL *segll;
|
||||
struct osmNode *nodes;
|
||||
|
||||
while(segids[count])
|
||||
while(ndids[count])
|
||||
count++;
|
||||
|
||||
segll = malloc(count * sizeof(struct osmSegLL));
|
||||
nodes = malloc(count * sizeof(struct osmNode));
|
||||
|
||||
if (!segll) {
|
||||
*segCount = 0;
|
||||
if (!nodes) {
|
||||
*ndCount = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = 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;
|
||||
|
||||
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++;
|
||||
}
|
||||
*segCount = count;
|
||||
return segll;
|
||||
*ndCount = count;
|
||||
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;
|
||||
struct osmSegLL *segll;
|
||||
int block, offset, ndCount = 0;
|
||||
struct osmNode *nodes;
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
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;
|
||||
|
||||
for (offset=0; offset < PER_BLOCK; offset++) {
|
||||
if (ways[block][offset].segids) {
|
||||
if (ways[block][offset].ndids) {
|
||||
way_out_count++;
|
||||
if (way_out_count % 1000 == 0)
|
||||
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);
|
||||
callback(id, ways[block][offset].tags, segll, segCount);
|
||||
free(segll);
|
||||
callback(id, ways[block][offset].tags, nodes, ndCount);
|
||||
free(nodes);
|
||||
}
|
||||
|
||||
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);
|
||||
ways[block][offset].tags = NULL;
|
||||
}
|
||||
if (ways[block][offset].segids) {
|
||||
free(ways[block][offset].segids);
|
||||
ways[block][offset].segids = NULL;
|
||||
if (ways[block][offset].ndids) {
|
||||
free(ways[block][offset].ndids);
|
||||
ways[block][offset].ndids = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -378,18 +325,14 @@ static void ram_stop(void)
|
||||
free(nodes[i]);
|
||||
nodes[i] = NULL;
|
||||
}
|
||||
if (segments[i]) {
|
||||
free(segments[i]);
|
||||
segments[i] = NULL;
|
||||
}
|
||||
if (ways[i]) {
|
||||
for (j=0; j<PER_BLOCK; j++) {
|
||||
if (ways[i][j].tags) {
|
||||
resetList(ways[i][j].tags);
|
||||
free(ways[i][j].tags);
|
||||
}
|
||||
if (ways[i][j].segids)
|
||||
free(ways[i][j].segids);
|
||||
if (ways[i][j].ndids)
|
||||
free(ways[i][j].ndids);
|
||||
}
|
||||
free(ways[i]);
|
||||
ways[i] = NULL;
|
||||
@ -403,8 +346,6 @@ struct middle_t mid_ram = {
|
||||
end: ram_end,
|
||||
cleanup: ram_stop,
|
||||
analyze: ram_analyze,
|
||||
segments_set: ram_segments_set,
|
||||
segments_get: ram_segments_get,
|
||||
nodes_set: ram_nodes_set,
|
||||
nodes_get: ram_nodes_get,
|
||||
ways_set: ram_ways_set,
|
||||
|
6
middle.h
6
middle.h
@ -1,7 +1,7 @@
|
||||
/* Common middle layer interface */
|
||||
|
||||
/* 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
|
||||
@ -15,14 +15,12 @@ struct middle_t {
|
||||
void (*cleanup)(void);
|
||||
void (*analyze)(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_get)(struct osmNode *out, int id);
|
||||
int (*ways_set)(int id, struct keyval *segs, struct keyval *tags);
|
||||
int *(*ways_get)(int id);
|
||||
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
|
||||
|
116
osm2pgsql.c
116
osm2pgsql.c
@ -46,20 +46,18 @@
|
||||
#include "input.h"
|
||||
|
||||
static int count_node, max_node;
|
||||
static int count_segment, max_segment;
|
||||
static int count_way, max_way;
|
||||
static int count_way_seg;
|
||||
static int count_rel, max_rel;
|
||||
|
||||
struct middle_t *mid;
|
||||
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
|
||||
start tag and can therefore be cached.
|
||||
*/
|
||||
static double node_lon, node_lat;
|
||||
static int seg_to, seg_from;
|
||||
static struct keyval tags, segs;
|
||||
static struct keyval tags, nds, members;
|
||||
static int osm_id;
|
||||
|
||||
int verbose;
|
||||
@ -67,14 +65,15 @@ int latlong;
|
||||
|
||||
static void printStatus(void)
|
||||
{
|
||||
fprintf(stderr, "\rProcessing: Node(%dk) Segment(%dk) Way(%dk)",
|
||||
count_node/1000, count_segment/1000, count_way/1000);
|
||||
fprintf(stderr, "\rProcessing: Node(%dk) Way(%dk) Relation(%dk)",
|
||||
count_node/1000, count_way/1000, count_rel/1000);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (xmlStrEqual(name, BAD_CAST "node")) {
|
||||
@ -97,25 +96,6 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
xmlFree(xid);
|
||||
xmlFree(xlon);
|
||||
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")) {
|
||||
xk = xmlTextReaderGetAttribute(reader, BAD_CAST "k");
|
||||
assert(xk);
|
||||
@ -147,14 +127,61 @@ void StartElement(xmlTextReaderPtr reader, const xmlChar *name)
|
||||
printStatus();
|
||||
|
||||
xmlFree(xid);
|
||||
} else if (xmlStrEqual(name, BAD_CAST "seg")) {
|
||||
xid = xmlTextReaderGetAttribute(reader, BAD_CAST "id");
|
||||
} else if (xmlStrEqual(name, BAD_CAST "nd")) {
|
||||
xid = xmlTextReaderGetAttribute(reader, BAD_CAST "ref");
|
||||
assert(xid);
|
||||
|
||||
if (addItem(&segs, "id", (char *)xid, 1))
|
||||
count_way_seg++;
|
||||
addItem(&nds, "id", (char *)xid, 0);
|
||||
|
||||
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")) {
|
||||
/* ignore */
|
||||
} else if (xmlStrEqual(name, BAD_CAST "bound")) {
|
||||
@ -171,17 +198,20 @@ void EndElement(const xmlChar *name)
|
||||
reproject(&node_lat, &node_lon);
|
||||
mid->nodes_set(osm_id, node_lat, node_lon, &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")) {
|
||||
mid->ways_set(osm_id, &segs, &tags);
|
||||
mid->ways_set(osm_id, &nds, &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")) {
|
||||
/* ignore */
|
||||
} else if (xmlStrEqual(name, BAD_CAST "seg")) {
|
||||
} else if (xmlStrEqual(name, BAD_CAST "nd")) {
|
||||
/* ignore */
|
||||
} else if (xmlStrEqual(name, BAD_CAST "member")) {
|
||||
/* ignore */
|
||||
} else if (xmlStrEqual(name, BAD_CAST "osm")) {
|
||||
printStatus();
|
||||
} else if (xmlStrEqual(name, BAD_CAST "bound")) {
|
||||
@ -338,7 +368,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
text_init();
|
||||
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
|
||||
|
||||
@ -366,12 +401,11 @@ int main(int argc, char *argv[])
|
||||
xmlCleanupParser();
|
||||
xmlMemoryDump();
|
||||
|
||||
if (count_node || count_segment || count_way) {
|
||||
if (count_node || count_way || count_rel) {
|
||||
fprintf(stderr, "\n");
|
||||
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: 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");
|
||||
//out->process(mid);
|
||||
|
12
osmtypes.h
12
osmtypes.h
@ -9,18 +9,6 @@ struct osmNode {
|
||||
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 */
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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';
|
||||
const char *amenity = getItem(tags, "amenity");
|
||||
@ -380,8 +363,6 @@ void add_parking_node(int id, struct keyval *tags, size_t index)
|
||||
if (name)
|
||||
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);
|
||||
|
||||
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
|
||||
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;
|
||||
unsigned int i;
|
||||
size_t wkt_size;
|
||||
int polygon = 0, export = 0;
|
||||
int roads = 0;
|
||||
char *wkt;
|
||||
double area;
|
||||
|
||||
for (i=0; i < numTags; i++) {
|
||||
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);
|
||||
|
||||
wkt_size = WKT(segll, count, polygon, id);
|
||||
|
||||
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 {
|
||||
write_wkts(id, tags, wkt, sql_conns[t_line]);
|
||||
if (roads)
|
||||
write_wkts(id, tags, wkt, sql_conns[t_roads]);
|
||||
}
|
||||
wkt = get_wkt(nodes, count, polygon, &area);
|
||||
if (wkt && strlen(wkt)) {
|
||||
/* FIXME: there should be a better way to detect polygons */
|
||||
if (!strncmp(wkt, "POLYGON", strlen("POLYGON"))) {
|
||||
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);
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
2
output.h
2
output.h
@ -19,7 +19,7 @@ struct output_t {
|
||||
void (*cleanup)(void);
|
||||
void (*process)(struct middle_t *mid);
|
||||
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
|
||||
|
Reference in New Issue
Block a user