|
From: <pg...@us...> - 2015-10-20 15:07:46
|
Revision: 2980
http://sourceforge.net/p/roadmap/code/2980
Author: pgf
Date: 2015-10-20 15:07:43 +0000 (Tue, 20 Oct 2015)
Log Message:
-----------
multipolygons and islands: still a work in progress
much of this commit has to do with calculating an accurate
bounding box for the shaped lines making up polygons
Modified Paths:
--------------
trunk/roadmap/src/buildmap_osm_text.c
trunk/roadmap/src/buildmap_polygon.c
trunk/roadmap/src/buildmap_polygon.h
trunk/roadmap/src/buildmap_tiger.c
Modified: trunk/roadmap/src/buildmap_osm_text.c
===================================================================
--- trunk/roadmap/src/buildmap_osm_text.c 2015-10-20 15:07:40 UTC (rev 2979)
+++ trunk/roadmap/src/buildmap_osm_text.c 2015-10-20 15:07:43 UTC (rev 2980)
@@ -98,7 +98,7 @@
struct wayinfo {
wayid_t id; // must be first
- int lineid;
+ int lineid, lineid2;
int layer;
int flags;
char *name;
@@ -115,6 +115,7 @@
/**
* @brief some global variables
*/
+static int LandmarkId = 0;
static int PolygonId = 0;
static int LineId = 0;
@@ -966,8 +967,6 @@
if (flags & AREA) {
if (way->node_refs[0] != way->node_refs[way->node_ref_count-1])
flags &= ~AREA;
- /* see http://wiki.openstreetmap.org/wiki/The_Future_of_Areas
- * for why the above conditions are simplistic */
}
@@ -984,7 +983,7 @@
wp->flags = flags;
} else {
wp->layer = relation_layer;
- wp->flags = relation_flags;
+ wp->flags = 0; // relation_flags;
}
}
wp->from = way->node_refs[0];
@@ -999,16 +998,25 @@
return READOSM_OK;
}
-void add_line_shapes(const readosm_way *way, int from, int to)
+void adjust_polybox(RoadMapArea *pbox, int lat, int lon)
{
- /*
- * We're passing too much here - the endpoints of
- * the line don't need to be passed to the shape
- * module. We're keeping them here just to be on
- * the safe side, they'll be ignored in
- * buildmap_osm_text_ways_shapeinfo().
- *
- * The lonsbuf/latsbuf are never freed, need to be
+ if (lon < pbox->west) {
+ pbox->west = lon;
+ } else if (lon > pbox->east) {
+ pbox->east = lon;
+ }
+
+ if (lat < pbox->south) {
+ pbox->south = lat;
+ } else if (lat > pbox->north) {
+ pbox->north = lat;
+ }
+}
+
+static void
+add_line_shapes(const readosm_way *way, int from, int to, RoadMapArea *pbox)
+{
+ /* The lonsbuf/latsbuf are never freed, need to be
* preserved for shape registration which happens
* at the end of the program run, so exit() will
* free this for us.
@@ -1029,6 +1037,8 @@
lonsbuf[i] = lon;
latsbuf[i] = lat;
+ if (pbox) adjust_polybox(pbox, lat, lon);
+
buildmap_square_adjust_limits(lon, lat);
}
@@ -1055,12 +1065,15 @@
nShapes++;
}
-int
-add_shaped_line(const readosm_way *way, int rms_name, int layer, int polygon)
+static int
+add_line(wayinfo *wp, const readosm_way *way, int rms_name, int layer,
+ int polygon, RoadMapArea *pbox)
{
RoadMapString rms_dirp, rms_dirs, rms_type;
- int from_point, to_point, mid_point, line, street;
+ int from_point, to_point, line, street;
+
+
rms_dirp = str2dict(DictionaryPrefix, "");
rms_dirs = str2dict(DictionarySuffix, "");
rms_type = str2dict(DictionaryType, "");
@@ -1078,7 +1091,7 @@
*/
int mid_count = way->node_ref_count / 2;
- mid_point = buildmap_osm_text_point_get(way->node_refs[mid_count]);
+ int mid_point = buildmap_osm_text_point_get(way->node_refs[mid_count]);
/* first half */
LineId++;
@@ -1089,8 +1102,10 @@
rms_dirs, line);
buildmap_range_add_no_address(line, street);
- add_line_shapes(way, 0, mid_count);
+ add_line_shapes(way, 0, mid_count, pbox);
+ wp->lineid = LineId;
+
if (polygon)
buildmap_polygon_add_line (0, PolygonId, LineId, POLYGON_SIDE_RIGHT);
@@ -1103,8 +1118,10 @@
rms_dirs, line);
buildmap_range_add_no_address(line, street);
- add_line_shapes(way, mid_count, way->node_ref_count-1);
+ add_line_shapes(way, mid_count, way->node_ref_count-1, pbox);
+ wp->lineid2 = LineId;
+
if (polygon)
buildmap_polygon_add_line (0, PolygonId, LineId, POLYGON_SIDE_RIGHT);
@@ -1118,7 +1135,10 @@
rms_dirs, line);
buildmap_range_add_no_address(line, street);
- add_line_shapes(way, 0, way->node_ref_count-1);
+ add_line_shapes(way, 0, way->node_ref_count-1, pbox);
+
+ wp->lineid = LineId;
+
if (polygon)
buildmap_polygon_add_line (0, PolygonId, LineId, POLYGON_SIDE_RIGHT);
}
@@ -1191,20 +1211,23 @@
}
} else if (wp->flags & AREA) {
+ RoadMapArea *polyarea;
add_as_poly:
+ LandmarkId++;
PolygonId++;
- buildmap_polygon_add_landmark (PolygonId, wp->layer, rms_name);
- buildmap_polygon_add(PolygonId, 0, PolygonId);
+ buildmap_info("adding %s as polygon %d", wp->name, PolygonId);
+ buildmap_polygon_add_landmark (LandmarkId, wp->layer, rms_name);
+ buildmap_polygon_add(LandmarkId, 0, PolygonId, &polyarea);
- wp->lineid = add_shaped_line(way, rms_name, wp->layer, 1);
+ add_line(wp, way, rms_name, wp->layer, 1, polyarea);
} else {
add_as_way:
buildmap_debug ("Way %lld [%s]", way->id,
wp->name ? wp->name : "");
- wp->lineid = add_shaped_line(way, rms_name,
- wp->layer ? wp->layer: wp->relation_layer, 0);
+ add_line(wp, way, rms_name,
+ wp->layer ? wp->layer: wp->relation_layer, 0, NULL);
}
return READOSM_OK;
}
@@ -1312,12 +1335,14 @@
return READOSM_OK;
}
-static void add_multipolygon(wayinfo **wayinfos, int layer, int rms_name, int count)
+static void add_multipolygon(wayinfo **wayinfos, int layer,
+ int rms_name, int count, char *name)
{
wayinfo *wp, *wp2;
nodeid_t from = 0, to = 0;
int ring = 0;
int i, j;
+ // RoadMapArea *polyarea;
for (i = 0; i < count; i++) {
wp = wayinfos[i];
@@ -1325,9 +1350,11 @@
wp->ring = ++ring;
PolygonId++;
- buildmap_polygon_add_landmark (PolygonId, layer, rms_name);
- buildmap_polygon_add(PolygonId, 0, PolygonId);
+ buildmap_info("add_multi: adding %s as polygon %d", name, PolygonId);
+ buildmap_polygon_add(LandmarkId, 0, PolygonId, 0); // &polyarea);
buildmap_polygon_add_line (0, PolygonId, wp->lineid, POLYGON_SIDE_RIGHT);
+ if (wp->lineid2)
+ buildmap_polygon_add_line (0, PolygonId, wp->lineid2, POLYGON_SIDE_RIGHT);
from = wp->from;
to = wp->to;
@@ -1344,16 +1371,22 @@
if (wp2->from == to) {
wp2->ring = ring;
// FIXME it's possible that a way may have more than one lineid, as
-// a result of being a circular way that's been split in two in add_shaped_line().
+// a result of being a circular way that's been split in two in add_line().
// we should record both and add both here.
buildmap_polygon_add_line (0, PolygonId, wp2->lineid,
POLYGON_SIDE_RIGHT);
+ if (wp2->lineid2)
+ buildmap_polygon_add_line (0, PolygonId, wp2->lineid2,
+ POLYGON_SIDE_RIGHT);
to = wp2->to;
j = i;
} else if (wp2->to == to) {
wp2->ring = ring;
buildmap_polygon_add_line (0, PolygonId, wp2->lineid,
POLYGON_SIDE_LEFT);
+ if (wp2->lineid2)
+ buildmap_polygon_add_line (0, PolygonId, wp2->lineid2,
+ POLYGON_SIDE_LEFT);
to = wp2->from;
j = i;
} else {
@@ -1387,11 +1420,11 @@
if (!rp)
return READOSM_OK;
- // buildmap_info("warning: relation %s is interesting", rp->name);
+ buildmap_info("warning: relation %s is interesting", rp->name);
// note: assumes this is a multipolygon relation
- PolygonId++;
+ LandmarkId++;
rms_name = str2dict(DictionaryStreet, rp->name);
@@ -1422,9 +1455,11 @@
}
}
- add_multipolygon(wayinfos, rp->layer, rms_name, wc);
+ buildmap_polygon_add_landmark (LandmarkId, rp->layer, rms_name);
+
+ add_multipolygon(wayinfos, rp->layer, rms_name, wc, rp->name);
// FIXME: shouldn't _always_ be l_island
- add_multipolygon(innerwayinfos, l_island, rms_name, iwc);
+ add_multipolygon(innerwayinfos, l_island, rms_name, iwc, rp->name);
free(wayinfos);
free(innerwayinfos);
Modified: trunk/roadmap/src/buildmap_polygon.c
===================================================================
--- trunk/roadmap/src/buildmap_polygon.c 2015-10-20 15:07:40 UTC (rev 2979)
+++ trunk/roadmap/src/buildmap_polygon.c 2015-10-20 15:07:43 UTC (rev 2980)
@@ -98,6 +98,8 @@
int count;
int sorted;
+ RoadMapArea area;
+
} BuildMapPolygon;
typedef struct {
@@ -246,11 +248,13 @@
}
}
-/* FIXME. this is called with the endpoints of every line. it
+/* this is called with the endpoints of every line. it
* misses all of the shape points for the line, so the bounding
* box is a poor approximation, at best. "long lines" have the
* same problem (but in practice, not as bad -- polygons tend to
* have bigger bounding boxes than lines, even long ones).
+ * this problem is fixed for OSM maps by calculating the fully-shaped
+ * bbox.
*/
static void buildmap_polygon_adjust_bbox
(RoadMapPolygon *polygon, int from, int to) {
@@ -304,12 +308,16 @@
BuildMapPolygonLine *this_line;
BuildMapPolygonLine *other_line;
RoadMapArea *pa = &polygon->area;
+ int adjust_bbox = 0;
first = polygon->first;
count = polygon->count;
- pa->west = pa->south = 180000000;
- pa->east = pa->north = -180000000;
+ if (pa->west == -1) {
+ adjust_bbox = 1;
+ pa->west = pa->south = 180000000;
+ pa->east = pa->north = -180000000;
+ }
end = first + count - 1;
@@ -320,7 +328,8 @@
buildmap_line_get_points_sorted (this_line->line, &from, &to);
- buildmap_polygon_adjust_bbox(polygon, from, to);
+ if (adjust_bbox)
+ buildmap_polygon_adjust_bbox(polygon, from, to);
if (this_line->side == POLYGON_SIDE_LEFT) {
/* draw from 'to' to 'from' */
@@ -408,7 +417,8 @@
this_line = PolygonLine[index/BUILDMAP_BLOCK] + (index % BUILDMAP_BLOCK);
buildmap_line_get_points_sorted (this_line->line, &from, &to);
- buildmap_polygon_adjust_bbox(polygon, from, to);
+ if (adjust_bbox)
+ buildmap_polygon_adjust_bbox(polygon, from, to);
/* check that the last line connects with the first */
if (this_line->side == POLYGON_SIDE_LEFT) {
@@ -510,7 +520,7 @@
}
-int buildmap_polygon_add (int landid, RoadMapString cenid, int polyid) {
+int buildmap_polygon_add (int landid, RoadMapString cenid, int polyid, RoadMapArea **areap) {
int block;
int offset;
@@ -523,7 +533,7 @@
this_landmark = buildmap_polygon_search_landmark (landid);
if (this_landmark == NULL) {
- return -1;
+ buildmap_fatal(0, "no landmark %d for polygon %d", landid, polyid);
}
block = PolygonCount / BUILDMAP_BLOCK;
@@ -553,6 +563,19 @@
this_polygon->square[2] = -1;
this_polygon->square[3] = -1;
+ if (areap) {
+ *areap = &this_polygon->area;
+ this_polygon->area.west = this_polygon->area.south = 180000000;
+ this_polygon->area.east = this_polygon->area.north = -180000000;
+ } else {
+ // attempt to preserve compatibility for tiger maps
+ // this will cause the bbox to be calculated in
+ // buildmap_polygon_fill_in_drawing_order(), as was
+ // done in the past. for OSM maps, it's done while
+ // we add the lines in buildmap_text_osm.c
+ this_polygon->area.west = -1;
+ }
+
this_polygon->count = 0;
roadmap_hash_add (PolygonByPolyid, polyid, PolygonCount);
@@ -984,6 +1007,7 @@
return 1;
}
db_poly->count = one_polygon->count;
+ db_poly->area = one_polygon->area;
square = one_polygon->square[0];
Modified: trunk/roadmap/src/buildmap_polygon.h
===================================================================
--- trunk/roadmap/src/buildmap_polygon.h 2015-10-20 15:07:40 UTC (rev 2979)
+++ trunk/roadmap/src/buildmap_polygon.h 2015-10-20 15:07:43 UTC (rev 2980)
@@ -27,7 +27,8 @@
#define POLYGON_SIDE_LEFT 0
#define POLYGON_SIDE_RIGHT 1
-int buildmap_polygon_add (int landid, RoadMapString cenid, int polyid);
+int buildmap_polygon_add
+ (int landid, RoadMapString cenid, int polyid, RoadMapArea **areap);
int buildmap_polygon_add_landmark
(int landid, int cfcc, RoadMapString name);
int buildmap_polygon_add_line
Modified: trunk/roadmap/src/buildmap_tiger.c
===================================================================
--- trunk/roadmap/src/buildmap_tiger.c 2015-10-20 15:07:40 UTC (rev 2979)
+++ trunk/roadmap/src/buildmap_tiger.c 2015-10-20 15:07:43 UTC (rev 2980)
@@ -990,7 +990,7 @@
cenid = tiger2string (dictionary_cenid, cursor, 11, 15);
polyid = tiger2int (cursor, 16, 25);
- buildmap_polygon_add (landid, cenid, polyid);
+ buildmap_polygon_add (landid, cenid, polyid, 0);
record_count += 1;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|