From 21e9ca674feb5f3176706742df45ec554c2d8685 Mon Sep 17 00:00:00 2001 From: Emillio Mariscal Date: Tue, 31 Oct 2023 14:35:13 -0300 Subject: [PATCH 1/4] WiP: refactor --- config/validate/highway.yaml | 668 -------- config/validate/landuse.yaml | 44 - config/validate/natural.yaml | 54 - config/validate/waterway.yaml | 52 - python/dbapi/api/raw.py | 29 +- python/restapi/config.py | 2 +- python/restapi/main.py | 8 + python/restapi/models.py | 1 + src/osm/osmchange.cc | 27 +- src/testsuite/libunderpass.all/val-test.cc | 32 +- .../testdata/validation/config/building.yaml | 1442 +++++++++++++++++ .../testdata/validation/config}/place.yaml | 1 + src/testsuite/testdata/validation/rect.osc | 223 +-- src/validate/geospatial.cc | 187 +++ src/validate/geospatial.hh | 93 ++ src/validate/{hotosm.cc => semantic.cc} | 117 +- src/validate/{hotosm.hh => semantic.hh} | 28 +- src/validate/validate.hh | 153 +- 18 files changed, 1873 insertions(+), 1288 deletions(-) delete mode 100644 config/validate/highway.yaml delete mode 100644 config/validate/landuse.yaml delete mode 100644 config/validate/natural.yaml delete mode 100644 config/validate/waterway.yaml create mode 100644 src/testsuite/testdata/validation/config/building.yaml rename {config/validate => src/testsuite/testdata/validation/config}/place.yaml (99%) create mode 100644 src/validate/geospatial.cc create mode 100644 src/validate/geospatial.hh rename src/validate/{hotosm.cc => semantic.cc} (74%) rename src/validate/{hotosm.hh => semantic.hh} (86%) diff --git a/config/validate/highway.yaml b/config/validate/highway.yaml deleted file mode 100644 index 20027ba9..00000000 --- a/config/validate/highway.yaml +++ /dev/null @@ -1,668 +0,0 @@ -tags: - - highway: - - motorway - - trunk - - primary - - secondary - - tertiary - - unclassified - - residential - - motorway_link - - trunk_link - - primary_link - - secondary_link - - tertiary_link - - living_street - - service - - pedestrian - - track - - bus_guideway - - escape - - raceway - - road - - busway - - footway - - bridleway - - steps - - corridor - - path - - bus_stop - - crossing - - elevator - - emergency_bay - - emergency_access_point - - give_way - - construction - - - construction - - footway: - - sidewalk - - crossing - - - sidewalk: - - both - - left - - right - - no - - - sidewalk:both:surface - - sidewalk:right:surface - - sidewalk:left:surface - - sidewalk:both:smoothness - - sidewalk:left:smoothness - - sidewalk:right:smoothness - - sidewalk:both:width - - sidewalk:right:width - - sidewalk:left:width - - sidewalk:both:est_width - - sidewalk:right:est_width - - sidewalk:left:est_width - - sidewalk:both:bicycle - - sidewalk:right:bicycle - - sidewalk:left:bicycle - - sidewalk:both:incline - - sidewalk:right:incline - - sidewalk:left:incline - - sidewalk:both:kerb - - sidewalk:right:kerb - - sidewalk:left:kerb - - sidewalk:both:wheelchair - - sidewalk:right:wheelchair - - sidewalk:left:wheelchair - - sidewalk:both:tactile_paving - - sidewalk:right:tactile_paving - - sidewalk:left:tactile_paving - - sidewalk:both:traffic_sign - - sidewalk:right:traffic_sign - - sidewalk:left:traffic_sign - - - est_width - - segregated - - yes - - no - - - cycleway - - cycleway: - - lane - - opposite - - opposite_lane - - track - - opposite_track - - share_busway - - opposite_share_busway - - shared_lane - - - lanes:psv - - lanes:backward - - lanes:forward - - - busway: - - lane - - bus_bay: - - both - - left - - right - - - parking:left - - parking:right - - parking:both - - parking: - - surface - - underground - - multi-storey - - rooftop - - carports - - garage_boxes - - sheds - - StreetParking - - lane - - street_side - - on_kerb - - half_on_kerb - - shoulder - - layby - - shoulder - - yes - - no - - left - - right - - both - - shoulder:width - - shoulder:left:width - - shoulder:right:width - - shoulder:surface - - shoulder:left:surface - - shoulder:right:surface - - shoulder:bicycle - - shoulder:left:bicycle - - shoulder:right:bicycle - - shoulder:smoothness - - shoulder:left:smoothness - - shoulder:right:smoothness - - shoulder:line - - shoulder:left:line - - shoulder:right:line - - - parking:sideorientation: - - parallel - - diagonal - - perpendicular - - proposed - - - abutters: - - commercial - - industrial - - mixed - - residential - - retailetc. - - - bicycle_road: - - yes - - bicycle - - oneway:bicycle - - - - change: - - yes - - no - - not_right - - not_left - - only_right - - only_left - - embankment: - - yes - - dyke - - destination - - yes - - ice_road: - - yes - - incline - - junction: - - roundabout - - lanes - - lit: - - yes - - no - - maxspeed - - motorroad: - - yes - - no - - mountain_pass: - - yes - - mtb:scale - - mtb:scale:uphill - - mtb:scale:imba - - mtb:description - - oneway: - - yes - - no - - reversible - - overtaking: - - yes - - no - - caution - - both - - forward - - backward - - - parking:lane: - - parallel - - diagonal - - perpendicular - - marked - - no_parking - - no_stopping - - fire_lane. - - parking:condition: - - free - - ticket - - disc - - residents - - customers - - private - - - passing_places: - - yes - - priority: - - forward - - backward - - priority_road: - - designated - - yes_unposted - - end - - sac_scale: - - hiking - - mountain_hiking - - demanding_mountain_hiking - - alpine_hiking - - demanding_alpine_hiking - - difficult_alpine_hiking - - service - - - smoothness: - - excellent - - good - - intermediate - - bad - - very_bad - - horrible - - very_horrible - - impassable - - surface: - - paved - - unpaved - - asphalt - - concrete - - paving_stones - - sett - - cobblestone - - metal - - wood - - compacted - - fine_gravel - - gravel - - pebblestone - - plastic - - grass_paver - - grass - - dirt - - earth - - mud - - sand - - ground - - - tactile_paving: - - yes - - no - - tracktype: - - grade1 - - grade2 - - grade3 - - grade4 - - grade5 - - traffic_calming - - trail_visibility: - - excellent - - good - - intermediate - - bad - - horrible - - no - - trailblazed: - - yes - - no - - poles - - cairns - - symbols - - trailblazed:visibility: - - excellent - - good - - intermediate - - bad - - horrible - - no - - turn: - - left - - slight_left - - through - - right - - slight_right - - merge_to_left - - merge_to_right - - reverse - - width - - winter_road: - - yes - - emergency: - - phone - - milestone - - mini_roundabout - - motorway_junction - - passing_place - - platform - - rest_area - - services - - speed_camera - - stop - - street_lamp - - toll_gantry - - traffic_mirror - - traffic_signals - - trailhead - - turning_circle - - turning_loop - - ref - - int_ref - - loc_ref - - local_ref - - nat_ref - - ncn_ref - - old_ref - - rcn_ref - - reg_ref - - route_ref - - noref - - yes - - bridge: - - yes - - aqueduct - - boardwalk - - cantilever - - covered - - low_water_crossing - - movable - - trestle - - viaduct - - source - - crossing:island - - access: - - yes - - no - - private - - permissive - - permit - - destination - - delivery - - customers - - designated - - use_sidepath - - dismount - - agricultural - - forestry - - discouraged - - variable - - unknown - - name - - name:left - - name:right - - int_name - - loc_name - - nat_name - - official_name - - old_name - - reg_name - - short_name - - sorting_name - - alt_name - - noname - - name:ab - - name:ace - - name:ady - - name:af - - name:ak - - name:alt - - name:am - - name:an - - name:ang - - name:ar - - name:arc - - name:as - - name:aus - - name:av - - name:ay - - name:az - - name:ba - - name:be - - name:bg - - name:bh - - name:bi - - name:bm - - name:bn - - name:bo - - name:br - - name:bru - - name:bs - - name:bug - - name:ca - - name:car - - name:cdo - - name:ce - - name:ceb - - name:ch - - name:chm - - name:chr - - name:chy - - name:co - - name:cs - - name:csb - - name:cu - - name:cv - - name:cy - - name:da - - name:de - - name:dsb - - name:dv - - name:dyu - - name:dz - - name:ee - - name:el - - name:en - - name:eo - - name:es - - name:et - - name:etymology - - name:etymology:wikidata - - name:etymology:wikipedia - - name:eu - - name:fa - - name:ff - - name:fi - - name:fo - - name:fr - - name:frr - - name:fur - - name:fy - - name:ga - - name:gcf - - name:gd - - name:gem - - name:gl - - name:gn - - name:grc - - name:gsw - - name:gu - - name:gv - - name:ha - - name:haw - - name:hi - - name:hif - - name:hop - - name:hr - - name:hsb - - name:ht - - name:hu - - name:hy - - name:ia - - name:id - - name:ie - - name:ig - - name:ilo - - name:inh - - name:io - - name:is - - name:it - - name:iu - - name:ja - - name:ja-Latn - - name:jbo - - name:jv - - name:ka - - name:ka-Latn - - name:kaa - - name:kab - - name:kbd - - name:kg - - name:kk - - name:kl - - name:km - - name:kmr - - name:kn - - name:ko - - name:koi - - name:kr - - name:krc - - name:krl - - name:ks - - name:ksh - - name:ku - - name:kum - - name:kv - - name:kw - - name:ky - - name:la - - name:lad - - name:language - - name:lb - - name:lbe - - name:left - - name:lez - - name:lg - - name:li - - name:lmo - - name:ln - - name:lo - - name:lrc - - name:lt - - name:lv - - name:mdf - - name:mg - - name:mhr - - name:mi - - name:min - - name:mk - - name:ml - - name:mn - - name:mos - - name:mr - - name:ms - - name:mt - - name:mwl - - name:my - - name:myv - - name:na - - name:nap - - name:nb - - name:ne - - name:nl - - name:nn - - name:no - - name:nov - - name:nso - - name:oc - - name:om - - name:or - - name:pa - - name:pag - - name:pap - - name:pfl - - name:pih - - name:pjt - - name:pl - - name:pnb - - name:prefix - - name:pronunciation - - name:ps - - name:pt - - name:pwn - - name:qu - - name:right - - name:rm - - name:rn - - name:ru - - name:rue - - name:rw - - name:sa - - name:sah - - name:sc - - name:scn - - name:sco - - name:sd - - name:se - - name:sg - - name:shn - - name:si - - name:signed - - name:sk - - name:skr - - name:sl - - name:sm - - name:sma - - name:sn - - name:so - - name:sq - - name:sr - - name:ss - - name:st - - name:su - - name:sv - - name:sw - - name:syc - - name:szl - - name:ta - - name:te - - name:tet - - name:tg - - name:th - - name:ti - - name:tk - - name:tl - - name:tlh - - name:tn - - name:to - - name:tpi - - name:tr - - name:ts - - name:tt - - name:tw - - name:ty - - name:udm - - name:ug - - name:uk - - name:ur - - name:uz - - name:vi - - name:vi-Hani - - name:vls - - name:vo - - name:wa - - name:war - - name:wikipedia - - name:wo - - name:xmf - - name:yi - - name:yo - - name:za - - name:zu - - foot: - - yes - - no - - designated - - permissive - - use_sidepath - - private - - destination - - lane_markings - - yes - - no - - motorcar: - - yes - - no - - designated - - agricultural - - private - - destination - - forestry - - permissive - - motor_vehicle - - motorcycle - - mofa - - vehicle - - horse - - layer - - maxweight - - flood_prone - - note - - material - - handrail - - maxspeed:type - - note diff --git a/config/validate/landuse.yaml b/config/validate/landuse.yaml deleted file mode 100644 index 80a24933..00000000 --- a/config/validate/landuse.yaml +++ /dev/null @@ -1,44 +0,0 @@ -tags: - - landuse: - - commercial - - construction - - education - - industrial - - residential - - retail - - institutional - - aquaculture - - allotments - - farmland - - farmyard - - flowerbed - - forest - - greenhouse_horticulture - - meadow - - orchard - - plant_nursery - - vineyard - - basin - - reservoir - - salt_pond - - brownfield - - cemetery - - conservation - - depot - - garages - - grass - - greenfield - - landfill - - military - - port - - quarry - - railway - - recreation_ground - - religious - - village_green - - winter_sports - - note - - - trees: - - olive_trees - - source \ No newline at end of file diff --git a/config/validate/natural.yaml b/config/validate/natural.yaml deleted file mode 100644 index 47e5ea05..00000000 --- a/config/validate/natural.yaml +++ /dev/null @@ -1,54 +0,0 @@ -tags: - - natural: - - fell - - grassland - - heath - - moor - - scrub - - shrubbery - - tree - - tree_row - - tree_stump - - tundra - - wood - - bay - - beach - - blowhole - - cape - - coastline - - crevasse - - geyser - - glacier - - hot_spring - - isthmus - - mud - - peninsula - - reef - - shingle - - shoal - - spring - - strait - - water - - wetland - - arch - - arete - - bare_rock - - cave_entrance - - cliff - - dune - - earth_bank - - fumarole - - gully - - hill - - peak - - ridge - - rock - - saddle - - sand - - scree - - sinkhole - - stone - - valley - - volcano - - note - - source \ No newline at end of file diff --git a/config/validate/waterway.yaml b/config/validate/waterway.yaml deleted file mode 100644 index 8d59a404..00000000 --- a/config/validate/waterway.yaml +++ /dev/null @@ -1,52 +0,0 @@ -tags: - - waterway: - - river - - riverbank - - stream - - tidal_channel - - canal - - pressurised - - drain - - ditch - - fairway - - fish_pass - - dock - - boatyard - - dam - - weir - - waterfall - - rapids - - lock_gate - - sluice_gate - - turning_point - - water_point - - fuel - - intermittent: - - yes - - seasonal: - - yes - - spring - - summer - - autumn - - winter - - wet_season - - dry_season - - destination: - - name - - lock: - - yes - - mooring: - - yes - - private - - no - - tunnel: - - culvert - - flooded - - bridge: - - aqueduct - - ref:fgkz - - ref:gnbc - - ref:gnis - - ref:regine - - note - - source \ No newline at end of file diff --git a/python/dbapi/api/raw.py b/python/dbapi/api/raw.py index 9c76ef7e..6c207d8f 100644 --- a/python/dbapi/api/raw.py +++ b/python/dbapi/api/raw.py @@ -57,6 +57,7 @@ def geoFeaturesQuery( dateFrom = None, dateTo = None, page = 0, + status = None, table = None): geoType = getGeoType(table) @@ -65,7 +66,7 @@ def geoFeaturesQuery( LEFT JOIN validation ON validation.osm_id = " + table + ".osm_id \ LEFT JOIN changesets c ON c.id = " + table + ".changeset \ WHERE \ - {0} {1} {2} {3} {4} \ + {0} {1} {2} {3} {4} {5} \ ), \ t_features AS ( \ SELECT jsonb_build_object( 'type', 'Feature', 'id', id, 'properties', to_jsonb(t_ways) \ @@ -76,6 +77,7 @@ def geoFeaturesQuery( "AND (" + tagsQueryFilter(tags, table) + ")" if tags else "", "AND " + hashtagQueryFilter(hashtag, table) if hashtag else "", "AND created at >= {0} AND created_at <= {1}".format(dateFrom, dateTo) if dateFrom and dateTo else "", + "AND status = '{0}'".format(status) if (status) else "", "LIMIT " + str(RESULTS_PER_PAGE), ) return query @@ -87,6 +89,7 @@ def listFeaturesQuery( page = 0, dateFrom = None, dateTo = None, + status = None, table = None, orderBy = "created_at" ): @@ -102,7 +105,7 @@ def listFeaturesQuery( LEFT JOIN validation ON validation.osm_id = " + table + ".osm_id \ LEFT JOIN changesets c ON c.id = " + table + ".changeset \ WHERE \ - {0} {1} {2} {3} {4} \ + {0} {1} {2} {3} {4} {5} \ ), t_features AS ( \ SELECT to_jsonb(t_ways) as feature from t_ways \ ) SELECT jsonb_agg(t_features.feature) as result FROM t_features;".format( @@ -110,8 +113,10 @@ def listFeaturesQuery( "AND (" + tagsQueryFilter(tags, table) + ")" if tags else "", "AND " + hashtagQueryFilter(hashtag, table) if hashtag else "", "AND created_at >= '{0}' AND created_at <= '{1}'".format(dateFrom, dateTo) if (dateFrom and dateTo) else "", + "AND status = '{0}'".format(status) if (status) else "", "ORDER BY " + orderBy + " DESC LIMIT " + str(RESULTS_PER_PAGE_LIST) + (" OFFSET {0}".format(page * RESULTS_PER_PAGE_LIST) if page else ""), ) + print("status", status) return query class Raw: @@ -126,6 +131,7 @@ def getPolygons( responseType = "json", dateFrom = None, dateTo = None, + status = None, page = None ): return self.underpassDB.run(geoFeaturesQuery( @@ -135,6 +141,7 @@ def getPolygons( dateFrom, dateTo, page, + status, "ways_poly" ), responseType, True) @@ -146,6 +153,7 @@ def getLines( responseType = "json", dateFrom = None, dateTo = None, + status = None, page = None ): return self.underpassDB.run(geoFeaturesQuery( @@ -155,6 +163,7 @@ def getLines( dateFrom, dateTo, page, + status, "ways_line" ), responseType, True) @@ -166,6 +175,7 @@ def getNodes( responseType = "json", dateFrom = None, dateTo = None, + status = None, page = None ): return self.underpassDB.run(geoFeaturesQuery( @@ -175,6 +185,7 @@ def getNodes( dateFrom, dateTo, page, + status, "nodes" ), responseType, True) @@ -186,6 +197,7 @@ def getAll( responseType = "json", dateFrom = None, dateTo = None, + status = None, page = None ): @@ -196,6 +208,7 @@ def getAll( responseType, dateFrom, dateTo, + status, page) lines = self.getLines( @@ -205,6 +218,7 @@ def getAll( responseType, dateFrom, dateTo, + status, page) nodes = self.getNodes( @@ -214,6 +228,7 @@ def getAll( responseType, dateFrom, dateTo, + status, page) result = {'type': 'FeatureCollection', 'features': []} @@ -237,6 +252,7 @@ def getPolygonsList( responseType = "json", dateFrom = None, dateTo = None, + status = None, page = None ): return self.underpassDB.run(listFeaturesQuery( @@ -246,6 +262,7 @@ def getPolygonsList( page, dateFrom, dateTo, + status, "ways_poly" ), responseType, True) @@ -257,6 +274,7 @@ def getLinesList( responseType = "json", dateFrom = None, dateTo = None, + status = None, page = None ): return self.underpassDB.run(listFeaturesQuery( @@ -266,6 +284,7 @@ def getLinesList( page, dateFrom, dateTo, + status, "ways_line" ), responseType, True) @@ -278,6 +297,7 @@ def getNodesList( responseType = "json", dateFrom = None, dateTo = None, + status = None, page = None ): return self.underpassDB.run(listFeaturesQuery( @@ -287,6 +307,7 @@ def getNodesList( page, dateFrom, dateTo, + status, "nodes" ), responseType, True) @@ -299,6 +320,7 @@ def getAllList( responseType = "json", dateFrom = None, dateTo = None, + status = None, page = None ): @@ -309,6 +331,7 @@ def getAllList( responseType, dateFrom, dateTo, + status, page) lines = self.getLinesList( @@ -318,6 +341,7 @@ def getAllList( responseType, dateFrom, dateTo, + status, page) nodes = self.getNodesList( @@ -327,6 +351,7 @@ def getAllList( responseType, dateFrom, dateTo, + status, page) result = [] diff --git a/python/restapi/config.py b/python/restapi/config.py index 69744904..e71dbf5d 100644 --- a/python/restapi/config.py +++ b/python/restapi/config.py @@ -1,4 +1,4 @@ import os # ENABLE_UNDERPASS_CORE=True -UNDERPASS_DB=os.getenv("UNDERPASS_API_DB") or "postgresql://localhost/underpass" +UNDERPASS_DB=os.getenv("UNDERPASS_API_DB") or "postgresql://localhost/underpass" \ No newline at end of file diff --git a/python/restapi/main.py b/python/restapi/main.py index 0e757e5a..379ff6d3 100644 --- a/python/restapi/main.py +++ b/python/restapi/main.py @@ -161,6 +161,7 @@ def getPolygons(request: RawRequest): hashtag = request.hashtag or "", dateFrom = request.dateFrom or "", dateTo = request.dateTo or "", + status = request.status or "", page = request.page ) return results @@ -173,6 +174,7 @@ def getNodes(request: RawRequest): hashtag = request.hashtag or "", dateFrom = request.dateFrom or "", dateTo = request.dateTo or "", + status = request.status or "", page = request.page ) return results @@ -185,6 +187,7 @@ def getLines(request: RawRequest): hashtag = request.hashtag or "", dateFrom = request.dateFrom or "", dateTo = request.dateTo or "", + status = request.status or "", page = request.page ) return results @@ -197,6 +200,7 @@ def getLines(request: RawRequest): hashtag = request.hashtag or "", dateFrom = request.dateFrom or "", dateTo = request.dateTo or "", + status = request.status or "", page = request.page ) return results @@ -209,6 +213,7 @@ def getPolygonsList(request: RawRequest): hashtag = request.hashtag or "", dateFrom = request.dateFrom or "", dateTo = request.dateTo or "", + status = request.status or "", page = request.page ) return results @@ -221,18 +226,21 @@ def getNodesList(request: RawRequest): hashtag = request.hashtag or "", dateFrom = request.dateFrom or "", dateTo = request.dateTo or "", + status = request.status or "", page = request.page ) return results @app.post("/raw/allList") def getAllList(request: RawRequest): + print("request.status", request.status) results = rawer.getAllList( area = request.area or None, tags = request.tags or "", hashtag = request.hashtag or "", dateFrom = request.dateFrom or "", dateTo = request.dateTo or "", + status = request.status or "", page = request.page, ) return results diff --git a/python/restapi/models.py b/python/restapi/models.py index 6cb3e648..f80cbf6b 100644 --- a/python/restapi/models.py +++ b/python/restapi/models.py @@ -17,4 +17,5 @@ class RawRequest(BaseModel): hashtag: str = None dateFrom: str = None dateTo: str = None + status: str = None page: int = None diff --git a/src/osm/osmchange.cc b/src/osm/osmchange.cc index d5a9705c..8f86593c 100644 --- a/src/osm/osmchange.cc +++ b/src/osm/osmchange.cc @@ -733,15 +733,6 @@ OsmChangeFile::validateWays(const multipolygon_t &poly, std::shared_ptrrefs.front() == way->refs.back()) { status->timestamp = boost::posix_time::microsec_clock::universal_time(); status->uid = way->uid; - - // Overlapping - if (plugin->overlaps(change->ways, *way)) { - status->status.insert(overlaping); - } - // Duplicate - if (plugin->duplicate(change->ways, *way)) { - status->status.insert(duplicate); - } // Bad geometry if (boost::geometry::num_points(way->linestring) - 1 < 4 || plugin->unsquared(way->linestring) @@ -757,15 +748,15 @@ OsmChangeFile::validateWays(const multipolygon_t &poly, std::shared_ptrpush_back(status); // Semantic checks - // std::vector way_tests = {"building", "highway", "landuse", "natural", "place", "waterway"}; - // for (auto test_it = way_tests.begin(); test_it != way_tests.end(); ++test_it) { - // if (way->containsKey(*test_it)) { - // auto status = plugin->checkWay(*way, *test_it); - // status->source = *test_it; - // boost::geometry::centroid(way->linestring, status->center); - // totals->push_back(status); - // } - // } + std::vector way_tests = {"building"}; + for (auto test_it = way_tests.begin(); test_it != way_tests.end(); ++test_it) { + if (way->containsKey(*test_it)) { + auto status = plugin->checkWay(*way, *test_it); + status->source = *test_it; + // boost::geometry::centroid(way->linestring, status->center); + totals->push_back(status); + } + } } } return totals; diff --git a/src/testsuite/libunderpass.all/val-test.cc b/src/testsuite/libunderpass.all/val-test.cc index ba20ca02..8022e65d 100644 --- a/src/testsuite/libunderpass.all/val-test.cc +++ b/src/testsuite/libunderpass.all/val-test.cc @@ -48,9 +48,9 @@ class TestOsmChange : public osmchange::OsmChangeFile {}; typedef std::shared_ptr(plugin_t)(); -// void test_semantic_building(std::shared_ptr &plugin); +int test_semantic_building(std::shared_ptr &plugin); // void test_semantic_highway(std::shared_ptr &plugin); -void test_geometry_building(std::shared_ptr &plugin); +int test_geometry_building(std::shared_ptr &plugin); int main(int argc, char *argv[]) @@ -60,7 +60,6 @@ main(int argc, char *argv[]) dbglogfile.setLogFilename("val-test.log"); dbglogfile.setVerbosity(3); -#if 1 std::string plugins(PKGLIBDIR); boost::dll::fs::path lib_path(plugins); boost::function creator; @@ -74,12 +73,12 @@ main(int argc, char *argv[]) log_debug("Couldn't load plugin! %1%", e.what()); exit(0); } + std::string testValidationConfig = DATADIR; + testValidationConfig += "/testsuite/testdata/validation/config"; auto plugin = creator(); -#else - auto plugin = std::make_shared(); -#endif + plugin->loadConfig(testValidationConfig); - // test_semantic_building(plugin); + test_semantic_building(plugin); // test_semantic_highway(plugin); test_geometry_building(plugin); } @@ -277,10 +276,27 @@ test_semantic_building(std::shared_ptr &plugin) { runtest.fail("Validate::checkWay(no bad values) [semantic building]"); return 1; } + + // Has spaces + way.addTag("building:material", "made of wood"); + status = plugin->checkWay(way, "building"); + if (status->hasStatus(badvalue)) { + runtest.pass("Validate::checkWay(bad values) [semantic building]"); + } else { + runtest.fail("Validate::checkWay(bad values) [semantic building]"); + return 1; + } + + + + // TODO: Has empty value + // TODO: Has single quote + // TODO: Has double quotes + // TODO: Has spaces } // Geometry tests for buildings -void +int test_geometry_building(std::shared_ptr &plugin) { diff --git a/src/testsuite/testdata/validation/config/building.yaml b/src/testsuite/testdata/validation/config/building.yaml new file mode 100644 index 00000000..519b6f9f --- /dev/null +++ b/src/testsuite/testdata/validation/config/building.yaml @@ -0,0 +1,1442 @@ + +config: + - minangle: + - 70 + - maxangle: + - 110 + - anglethreshold: + - 19 + - overlaps: + - yes + - duplicate: + - yes + - enable_tag_values: + - yes + +tags: + - building: + - apartments + - barracks + - bungalow + - cabin + - detached + - dormitory + - farm + - ger + - hotel + - house + - houseboat + - residential + - semidetached_house + - static_caravan + - stilt_house + - terrace + - tree_house + - commercial + - industrial + - kiosk + - office + - retail + - supermarket + - warehouse + - cathedral + - chapel + - church + - kingdom_hall + - monastery + - mosque + - presbytery + - religious + - shrine + - synagogue + - temple + - bakehouse + - bridge + - civic + - college + - fire_station + - government + - gatehouse + - hospital + - kindergarten + - public + - school + - toilets + - train_station + - transportation + - university + - barn + - conservatory + - cowshed + - farm_auxiliary + - greenhouse + - slurry_tank + - stable + - sty + - grandstand + - pavilion + - riding_hall + - sports_hall + - stadium + - hangar + - hut + - shed + - carport + - garage + - garages + - parking + - digester + - service + - transformer_tower + - water_tower + - storage_tank + - silo + - beach_hut + - bunker + - castle + - construction + - container + - military + - roof + - ruins + - tent + - yes + + - building:levels + + - building:structure: + - confined_masonry + - steel_frame + - wood_frame + - bamboo_frame + - reinforced_masonry + - unreinforced_masonry + - plastered + - RCC_with_beam + - non_engineered_reinforced_concrete + - engineered_reinforced_concrete + - load_bearing_brick_wall_in_cement_mortar + - brick + - cement_blocks + - steel_frame + - concrete + + - building:material: + - cement_block + - brick + - plaster + - wood + - concrete + - metal + - steel + - stone + - glass + - mirror + - mud + - masonry + - tin + - plastic + - timber_framing + - sandstone + - clay + - reed + - loam + - marble + - copper + - slate + - vinyl + - limestone + - tiles + - metal_plates + - bamboo + - adobe + - rammed_earth + - solar_panels + - tyres + + - roof:material: + - roof_tiles + - metal + - concrete + - tar_paper + - asbestos + - eternit + - glass + - metal_sheet + - slate + - tin + - grass + - copper + - thatch + - gravel + - stone + - wood + - plastic + - asphalt + - zinc + - sandstone + - bamboo + - palm_leaves + - banana_leaves + - solar_panels + - titanium + + - roof:shape: + - gabled + - round + - saltbox + - double_saltbox + - quadruple_saltbox + - sawtooth + - cone + - conical + - side_hipped + - lean_to + - shed + - gabled_row + - crosspitched + - parabolic + - many + - gabled + - flat + - hipped + - pyramidal + - skillion + - half-hipped + - gambrel + - mansard + - dome + - onion + - roof:orientation + - along + - across + - roof:height + - roof:angle + - roof:levels + - roof:direction + - roof:material + - roof:colour + + - floor:material: + - plaster + - brick + - wood + - concrete + - glass + - stone + - asphalt + - metal + - marble + - mdf + - timber_framing + + - building:condition: + - good + - average + - poor + - disused + + - building:colour + - building:fireproof: + - yes + - no + - building:flats + - building:levels + - building:min_level + - building:part + - building:soft_storey: + - yes + - no + - reinforced + + - entrance: + - yes + - main + - exit + - service + - emergency + - height + - max_level + - min_level + - non_existent_levels + - start_date + + - shop: + - alcohol + - art + - bakery + - beauty + - beverages + - bicycle + - books + - butcher + - car + - car_parts + - car_repair + - chemist + - clothes + - convenience + - copyshop + - cosmetics + - charcoal + - electronics + - farm + - furniture + - general + - greengrocer + - hairdresser + - hardware + - houseware + - jewellery + - kiosk + - mobile_phone + - pastry + - shoes + - stationary + - supermarket + - tailor + - tea + - department_store + - general + - mall + - hardware + - laundry + - trade + - office: + - accountant + - administrative + - advertising_agency + - architect + - association + - chamber + - charity + - company + - construction_company + - consulting + - courier + - coworking + - diplomatic + - educational_institution + - employment_agency + - energy_supplier + - engineer + - estate_agent + - financial + - financial_advisor + - forestry + - foundation + - geodesist + - government + - graphic_design + - guide + - harbour_master + - insurance + - it + - lawyer + - logistics + - moving_company + - newspaper + - ngo + - notary + - politician + - political_party + - property_management + - quango + - religion + - research + - security + - surveyor + - tax_advisor + - telecommunication + - therapist + - travel_agent + - tutoring + - union + - visa + - water_utility + - yes + - religious: + - church + - mosque + - temple + - shrine + - cathedral + - chapel + - synagogue + - religion: + - muslim + - hindu + - christian + - buddhist + - jewish + - bahai + - capacity_persons: + - <50 + - 50-100 + - 100-250 + - 250-500 + - >500 + + - denomination: + - gelug + - jishu + - jodo_shinshu + - jodo_shu + - nichiren + - nyingma + - obaku + - pure_land + - rinzai + - risshu + - shingon_shu + - soto + - tiantai + - tibetan + - vajrayana + - won + - yogacara + - yuzu_nembutsu + - zen + - thai_mahanikaya + - thai_thammayut + - catholic + - armenian_catholic + - chaldean_catholic + - coptic_catholic + - eritrean_catholic + - ethiopian_catholic + - greek_catholic + - hungarian_greek_catholic + - maronite + - polish_catholic + - roman_catholic + - romanian_catholic + - syriac_catholic + - syro-malabar_catholic + - ukrainian_greek_catholic + - orthodox + - antiochian_orthodox + - armenian_apostolic + - bulgarian_orthodox + - eritrean_orthodox + - ethiopian_orthodox + - coptic_orthodox + - georgian_orthodox + - greek_orthodox + - macedonian_orthodox + - old_believers + - romanian_orthodox + - russian_orthodox + - serbian_orthodox + - syriac_orthodox + - ukrainian_orthodox + - protestant + - adventist + - anglican + - baptist + - disciples_of_christ + - episcopal + - evangelical + - evangelical_covenant + - exclusive_brethren + - lutheran + - mennonite + - methodist + - moravian + - pentecostal + - presbyterian + - quaker + - reformed + - uniting + - polish_national_catholic + - african_methodist_episcopal + - african_methodist_episcopal_zion + - alliance + - apostolic_faith + - assemblies_of_god + - calvinistic_methodist + - catholic_apostolic + - church_of_god_in_christ + - church_of_scotland + - churches_of_christ + - czechoslovak_hussite + - disciples_of_christ + - dutch_reformed + - evangelical_covenant + - evangelical_free_church_of_america + - evangelical_lutheran + - evangelical_free_church_of_france + - exclusive_brethren + - foursquare + - free_church_of_scotland + - living_waters_church + - mission_covenant_church_of_sweden + - moravian + - mormon + - nazarene + - new_frontiers + - orthodox_presbyterian_church + - pkn + - remonstrant + - salvation_army + - scottish_episcopal + - seventh_day_adventist + - strict_baptist + - temple_society_australia + - united + - united_free_church_of_scotland + - united_reformed + - uniting + - united_methodist + - united_church_of_christ + - welsh_baptist + - welsh_independent + - apostolic + - assyrian + - catholic_mariavite + - charismatic + - christian_community + - christ_scientist + - church_of_christ + - congregational + - ecumenical + - fsspx + - harrist + - iglesia_ni_cristo + - jehovahs_witness + - kimbanguist + - la_luz_del_mundo + - liberal_catholic + - mariavite + - messianic_jewish + - new_apostolic + - nondenominational + - old_catholic + - philippine_independent + - simultaneum + - spiritist + - shaktism + - hare_krishna + - vaishnavism + - shaivism + - smartism + - nondenominational + - ahmadiyya + - alevi + - bektashi + - ibadi + - ismaili + - shia + - sunni + - sufi + - digambara + - svetambara + - nondenominational + - unaffiliated + - ashkenazi + - buchari + - conservative + - hasidic + - kabbalistic + - karaite + - lubavitch + - mizrachi + - modern_orthodox + - neo_orthodox + - orthodox + - reconstructionist + - reform + - progressive + - liberal + - samaritan + - sephardi + - traditional + - unity + - asatru + - celtic + - greco-roman + - slavic + - wicca + - quanzhen + - zhengyi + - irani + - parsi + - water_source: + - water_works + - manual_pump + - powered_pump + - groundwater + - historic: + - archaeological_site + - building + - fort + - monument + - area + - housing: + - residential + - hotel + - camp_site + - camp_pitch + - apartments + - toilet + - service: + - car_repair + - electronics_repair + - pump_station + - copyshop + - beauty + - service + - tailor + - cuisine: + - afghan + - african + - american + - arab + - argentinian + - armenian + - asian + - australian + - austrian + - balkan + - bangladeshi + - basque + - bavarian + - belgian + - bolivian + - brazilian + - british + - bulgarian + - cajun + - cambodian + - cantonese + - caribbean + - chinese + - colombian + - croatian + - cuban + - czech + - danish + - dutch + - egyptian + - ethiopian + - european + - filipino + - french + - georgian + - german + - greek + - hawaiian + - hungarian + - indian + - indonesian + - irish + - italian + - jamaican + - japanese + - jewish + - korean + - lao + - latin_american + - lebanese + - malagasy + - malaysian + - mediterranean + - mexican + - middle_eastern + - mongolian + - moroccan + - nepalese + - oriental + - pakistani + - persian + - peruvian + - polish + - portuguese + - romanian + - russian + - senegalese + - serbian + - southern + - spanish + - sri_lankan + - swedish + - swiss + - syrian + - taiwanese + - tex-mex + - thai + - tibetan + - turkish + - ukrainian + - uzbek + - venezuelan + - vietnamese + - western + - açaí + - bagel + - beef + - beef_bowl + - beef_noodle + - bougatsa + - bubble_tea + - burger + - cake + - chicken + - chili + - chocolate + - churro + - coffee_shop + - couscous + - crepe + - curry + - donut + - dumpling + - empanada + - falafel + - fish + - fish_and_chips + - fondue + - fried_chicken + - fries + - frozen_yogurt + - gyoza + - gyros + - hot_dog + - hotpot + - ice_cream + - juice + - kebab + - meat + - noodle + - pancake + - pasta + - pastry + - piadina + - pie + - pita + - pizza + - poke + - potato + - pretzel + - ramen + - salad + - sandwich + - sausage + - savory_pancakes + - seafood + - shawarma + - smoothie + - smørrebrød + - soba + - soup + - souvlaki + - steak + - sushi + - tacos + - takoyaki + - tea + - udon + - waffle + - wings + - yakitori + - bakery + - bar&grill + - barbecue + - bistro + - brasserie + - breakfast + - brunch + - buffet + - buschenschank + - cafe + - deli + - dessert + - diner + - fast_food + - fine_dining + - fried_food + - friture + - fusion + - grill + - heuriger + - international + - local + - lunch + - pub + - regional + - snack + - steak_house + - tapas + - yakiniku + - amenity: + - bar + - cafe + - fast_food + - food_court + - ice_cream + - pub + - restaurant + - college + - driving_school + - kindergarten + - language_school + - library + - toy_library + - training + - music_school + - school + - university + - bus_station + - car_rental + - car_sharing + - car_wash + - vehicle_inspection + - ferry_terminal + - fuel + - parking + - bank + - bureau_de_change + - baby_hatch + - clinic + - dentist + - doctors + - hospital + - nursing_home + - pharmacy + - social_facility + - veterinary + - arts_centre + - brothel + - casino + - cinema + - community_centre + - conference_centre + - events_venue + - gambling + - love_hotel + - nightclub + - planetarium + - public_bookcase + - social_centre + - stripclub + - studio + - swingerclub + - theatre + - courthouse + - fire_station + - police + - post_depot + - post_office + - prison + - ranger_station + - townhall + - dressing_room + - give_box + - mailroom + - parcel_locker + - shelter + - toilets + - recycling + - waste_disposal + - waste_transfer_station + - animal_boarding + - animal_breeding + - animal_shelter + - baking_oven + - childcare + - clock + - crematorium + - funeral_hall + - hunting_stand + - internet_cafe + - marketplace + - monastery + - place_of_mourning + - place_of_worship + - public_building + - refugee_site + - tourism: + - camp_site + - taxi + - camp pitch + - caravan_site + - artwork + - gallery + - museum + - zoo + - attraction + - guest_house + - hotel + - hostel + - generator:source: + - grid + - generator + - solar + - hydro + - ref:bag + - addr:housenumber + - addr:housename + - addr:flats + - addr:conscriptionnumber + - addr:street + - addr:place + - addr:postcode + - addr:city + - addr:country + - addr:postbox + - addr:full + - addr:hamlet + - addr:suburb + - addr:subdistrict + - addr:district + - addr:province + - addr:state + - addr:county + - addr:interpolation + - addr:inclusion + - addr:door + - addr:unit + - addr:flats + - addr:floor + - addr:block + - addr:block_number + - roof:colour + - roof:height + - layer + + - name + - name:left + - name:right + - int_name + - loc_name + - nat_name + - official_name + - old_name + - reg_name + - short_name + - sorting_name + - alt_name + - noname + - name:ab + - name:ace + - name:ady + - name:af + - name:ak + - name:alt + - name:am + - name:an + - name:ang + - name:ar + - name:arc + - name:as + - name:aus + - name:av + - name:ay + - name:az + - name:ba + - name:be + - name:bg + - name:bh + - name:bi + - name:bm + - name:bn + - name:bo + - name:br + - name:bru + - name:bs + - name:bug + - name:ca + - name:car + - name:cdo + - name:ce + - name:ceb + - name:ch + - name:chm + - name:chr + - name:chy + - name:co + - name:cs + - name:csb + - name:cu + - name:cv + - name:cy + - name:da + - name:de + - name:dsb + - name:dv + - name:dyu + - name:dz + - name:ee + - name:el + - name:en + - name:eo + - name:es + - name:et + - name:etymology + - name:etymology:wikidata + - name:etymology:wikipedia + - name:eu + - name:fa + - name:ff + - name:fi + - name:fo + - name:fr + - name:frr + - name:fur + - name:fy + - name:ga + - name:gcf + - name:gd + - name:gem + - name:gl + - name:gn + - name:grc + - name:gsw + - name:gu + - name:gv + - name:ha + - name:haw + - name:hi + - name:hif + - name:hop + - name:hr + - name:hsb + - name:ht + - name:hu + - name:hy + - name:ia + - name:id + - name:ie + - name:ig + - name:ilo + - name:inh + - name:io + - name:is + - name:it + - name:iu + - name:ja + - name:ja-Latn + - name:jbo + - name:jv + - name:ka + - name:ka-Latn + - name:kaa + - name:kab + - name:kbd + - name:kg + - name:kk + - name:kl + - name:km + - name:kmr + - name:kn + - name:ko + - name:koi + - name:kr + - name:krc + - name:krl + - name:ks + - name:ksh + - name:ku + - name:kum + - name:kv + - name:kw + - name:ky + - name:la + - name:lad + - name:language + - name:lb + - name:lbe + - name:left + - name:lez + - name:lg + - name:li + - name:lmo + - name:ln + - name:lo + - name:lrc + - name:lt + - name:lv + - name:mdf + - name:mg + - name:mhr + - name:mi + - name:min + - name:mk + - name:ml + - name:mn + - name:mos + - name:mr + - name:ms + - name:mt + - name:mwl + - name:my + - name:myv + - name:na + - name:nap + - name:nb + - name:ne + - name:nl + - name:nn + - name:no + - name:nov + - name:nso + - name:oc + - name:om + - name:or + - name:pa + - name:pag + - name:pap + - name:pfl + - name:pih + - name:pjt + - name:pl + - name:pnb + - name:prefix + - name:pronunciation + - name:ps + - name:pt + - name:pwn + - name:qu + - name:right + - name:rm + - name:rn + - name:ru + - name:rue + - name:rw + - name:sa + - name:sah + - name:sc + - name:scn + - name:sco + - name:sd + - name:se + - name:sg + - name:shn + - name:si + - name:signed + - name:sk + - name:skr + - name:sl + - name:sm + - name:sma + - name:sn + - name:so + - name:sq + - name:sr + - name:ss + - name:st + - name:su + - name:sv + - name:sw + - name:syc + - name:szl + - name:ta + - name:te + - name:tet + - name:tg + - name:th + - name:ti + - name:tk + - name:tl + - name:tlh + - name:tn + - name:to + - name:tpi + - name:tr + - name:ts + - name:tt + - name:tw + - name:ty + - name:udm + - name:ug + - name:uk + - name:ur + - name:uz + - name:vi + - name:vi-Hani + - name:vls + - name:vo + - name:wa + - name:war + - name:wikipedia + - name:wo + - name:xmf + - name:yi + - name:yo + - name:za + - name:zu + + - stars + - opening_hours + - operator + - operator:type: + - private + - public + - government + - community + - consortium + - cooperative + - military + - ngo + - religious + - charitable + - leisure: + - adult_gaming_centre + - amusement_arcade + - bandstand + - bird_hide + - bowling_alley + - dance + - escape_game + - fitness_centre + - hackerspace + - ice_rink + - sports_centre + - sports_hall + - stadium + - tanning_salon + - trampoline_park + - wildlife_hide + - phone + - contact:phone + - email + - contact:email + - website + - contact:website + - capacity:persons + - brand + - abandoned + - yes + - branch + - brand:wikidata + - brand:wikipedia + - takeaway + + - payment:cash + - payment:coins + - payment:notes + - payment:cheque + - payment:electronic_purses + - payment:cards + - payment:debit_cards + - payment:credit_cards + - payment:contactless + - payment:electronic_purses + - payment:stored_value_card + - payment:ep_avant + - payment:ep_beep + - payment:ep_brizzi + - payment:ep_bsbcash + - payment:ep_cash + - payment:ep_flazz + - payment:ep_geldkarte + - payment:ep_mach + - payment:ep_mandiri_emoney + - payment:ep_megacash + - payment:ep_mep + - payment:ep_minicash + - payment:ep_minipay + - payment:ep_monedero + - payment:ep_monedero4b + - payment:ep_nobu_emoney + - payment:ep_stwm_legic + - payment:ep_tapcash + - payment:octopus + - payment:mercado_pago + - payment:debit_cards + - payment:bancomat + - payment:bancontact + - payment:bankaxept + - payment:bankaxess + - payment:cb + - payment:coinkite + - payment:cuentarut + - payment:eps + - payment:girocardpayment:girocard_contactless + - payment:gpn_debit + - payment:interac + - payment:laser + - payment:maestro + - payment:mastercard_debit + - payment:mir + - payment:multibanco + - payment:postfinance_card + - payment:unionpay_debit + - payment:v_pay + - payment:visa_debit + - payment:visa_electron + - payment:credit_cards + - payment:american_express + - payment:bca_card + - payment:dinacard + - payment:diners_club + - payment:discover_card + - payment:jcb + - payment:mastercard + - payment:unionpay + - payment:visa + - payment:contactless + - payment:mastercard_contactlesspayment:paypasspayment:mastercard_paypass + - payment:visa_contactlesspayment:visa_paywavepayment:paywave + - payment:american_express_contactlesspayment:expresspay + - payment:girocard_contactless + - payment:interac_contactless + - payment:maestro_contactless + - payment:quickpass + - payment:rupay_contactless + - payment:berlio + - payment:cfn + - payment:circlek + - payment:dci + - payment:dkv + - payment:esso_card + - payment:eurowag + - payment:hoyer_card + - payment:ids + - payment:omv_card + - payment:petrochina + - payment:roadrunner + - payment:routex + - payment:sinopec + - payment:shell + - payment:snnp + - payment:svg + - payment:total_card + - payment:uta + - payment:sms + - payment:phonepayment:toll_number + - payment:app + - payment:mobile_phone + - payment:telephone_cards + - payment:calling_cards + - payment:reverse_charge_calls + - payment:my_pertamina_app + - payment:parkee_app + - payment:payback_app + - payment:payconiq_app + - payment:payme + - payment:spb + - payment:bob + - payment:china_t-union + - payment:clipper + - payment:ic + - payment:icsf + - payment:ep_ipass + - payment:easycardpayment:ep_easycard + - payment:jak_lingko + - payment:ov-chipkaart + - payment:oyster + - payment:prepaid_ticket + - payment:presto + - payment:sube + - payment:license_plate + - payment:touchngo + - payment:touchngo_smarttag + - payment:touchngo_rfid + - payment:autosweep_rfid + - payment:easytrip + - payment:e_pass + - payment:e_zpass + - payment:fastrak + - payment:k-tag + - payment:good_to_go + - payment:i-pass + - payment:nc_quick_pass + - payment:peach_pass + - payment:pikepass + - payment:sunpass + - payment:via_verde + - payment:cryptocurrencies + - payment:bitcoin + - payment:lightning + - payment:lightning_contactless + - payment:bitcoincash + - payment:litecoin + - payment:dogecoin + - payment:ethereum + - payment:dash + - payment:akulaku + - payment:alipay + - payment:apple_pay + - payment:au_pay + - payment:bcapayment:bca:gpn_qris=yespayment:sakuku + - payment:blik + - payment:bluepaypayment:bluepay:gpn_qris=yes + - payment:cashbac + - payment:d_barai + - payment:danapayment:dana:gpn_qris=yes + - payment:e-cny + - payment:edy + - payment:gcash + - payment:google_paypayment:android_pay + - payment:gopay_idpayment:id_gopay:gpn_qris=yes + - payment:gopay_my + - payment:gpn_qris + - payment:grabpay + - payment:huawei_pay + - payment:id + - payment:isakupayment:isaku:gpn_qris + - payment:kaspro + - payment:line_pay + - payment:jko_pay + - payment:linkaja + - payment:maya + - payment:mbway + - payment:merpay + - payment:mipay + - payment:nanaco + - payment:oplati + - payment:ovo + - payment:paypay + - payment:quicpay + - payment:rakuten_pay + - payment:samsung_pay + - payment:satispay + - payment:sgqr + - payment:shopeepaypayment:shopeepay:gpn_qris + - payment:swish + - payment:touchngo + - payment:twint + - payment:venmo + - payment:vipps + - payment:waon + - payment:wechat + - payment:yukkpayment:yukk:gpn_qris + - payment:zip + - payment:ebt + - payment:snap + - payment:wic + - payment:wire_transfer + - payment:bank_transfer + - payment:invoice + - payment:paypal + - payment:service_voucher + - payment:meal_voucher + - payment:token + - payment:token_coin + - payment:gift_card + - payment:account_cards + - payment:szep + - payment:posta_paletta + - payment:edenred_card + - payment:edenred_voucher + - payment:otp_cafeteria + - payment:multipay + - payment:museumkaart + - payment:u-key + - payment:none + - safety:mask:covid19: + - yes + - no + - given + - sold + - note + - healthcare + - clinic + - hospital + - dentist + - doctor + - pharmacy + - source + - destroyed:building + - yes diff --git a/config/validate/place.yaml b/src/testsuite/testdata/validation/config/place.yaml similarity index 99% rename from config/validate/place.yaml rename to src/testsuite/testdata/validation/config/place.yaml index f429a15a..cd83ead7 100644 --- a/config/validate/place.yaml +++ b/src/testsuite/testdata/validation/config/place.yaml @@ -1,3 +1,4 @@ + required_tags: - name diff --git a/src/testsuite/testdata/validation/rect.osc b/src/testsuite/testdata/validation/rect.osc index b5e1a13c..71a8e3ad 100644 --- a/src/testsuite/testdata/validation/rect.osc +++ b/src/testsuite/testdata/validation/rect.osc @@ -1,22 +1,6 @@ - - - - - - - - - - - - - - - - - + @@ -32,209 +16,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/validate/geospatial.cc b/src/validate/geospatial.cc new file mode 100644 index 00000000..1b2e43a9 --- /dev/null +++ b/src/validate/geospatial.cc @@ -0,0 +1,187 @@ +// +// Copyright (c) 2020, 2021, 2022, 2023 Humanitarian OpenStreetMap Team +// +// This file is part of Underpass. +// +// Underpass is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Underpass is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Underpass. If not, see . +// + +#ifndef __GEOSPATIAL_H__ +#define __GEOSPATIAL_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "utils/yaml.hh" +#include "geospatial.hh" +#include "validate.hh" +#include "osm/osmchange.hh" +#include "utils/log.hh" + +using namespace logger; + +// This plugin checks for geospatial issues +// [*] Bad geometry +// [ ] Overlapping +// [ ] Duplicates +// [ ] Un-connected + +namespace geospatial { + +LogFile &dbglogfile = LogFile::getDefaultInstance(); + +Geospatial::Geospatial(void) {} + +// Check a POI for tags. A node that is part of a way shouldn't have any +// tags, this is to check actual POIs, like a school. +std::shared_ptr +Geospatial::checkPOI(const osmobjects::OsmNode &node, const std::string &type) +{ + auto status = std::make_shared(node); + return status; +} + +// This checks a way. A way should always have some tags. Often a polygon +// with no tags is a building. +std::shared_ptr +Geospatial::checkWay(const osmobjects::OsmWay &way, const std::string &type) +{ + auto status = std::make_shared(way); + return status; +} + +bool +Geospatial::overlaps(const std::list> &allways, osmobjects::OsmWay &way) { + // This test only applies to buildings, as highways often overlap. + // TODO: move logic to a config file + yaml::Yaml tests = yamls["building"]; + if (tests.get("config").contains_value("overlaps", "yes")) { +#ifdef TIMING_DEBUG_X + boost::timer::auto_cpu_timer timer("validate::overlaps: took %w seconds\n"); +#endif + if (way.numPoints() <= 1) { + return false; + } + for (auto nit = std::begin(allways); nit != std::end(allways); ++nit) { + osmobjects::OsmWay *oldway = nit->get(); + if (boost::geometry::overlaps(oldway->polygon, way.polygon)) { + if (way.getTagValue("layer") == oldway->getTagValue("layer") && way.id != oldway->id) { + log_error("Building %1% overlaps with %2%", way.id, oldway->id); + return true; + } + } + } + } + return false; +} + +bool +Geospatial::duplicate(const std::list> &allways, osmobjects::OsmWay &way) { + // This test only applies to buildings, as highways often overlap. + // TODO: move logic to a config file + yaml::Yaml tests = yamls["building"]; + if (tests.get("config").contains_value("duplicate", "yes")) { +#ifdef TIMING_DEBUG_X + boost::timer::auto_cpu_timer timer("validate::duplicate: took %w seconds\n"); +#endif + if (way.numPoints() <= 1) { + return false; + } + + for (auto nit = std::begin(allways); nit != std::end(allways); ++nit) { + osmobjects::OsmWay *oldway = nit->get(); + std::deque output; + bg::intersection(oldway->polygon, way.polygon, output); + double iarea = 0; + for (auto& p : output) + iarea += bg::area(p); + double wayarea = bg::area(way.polygon); + double iareapercent = (iarea * 100) / wayarea; + if (iareapercent >= 80) { + if (way.getTagValue("layer") == oldway->getTagValue("layer") && way.id != oldway->id) { + log_error("Building %1% duplicate %2%", way.id, oldway->id); + return true; + } + } + } + } + return false; +} + +bool +Geospatial::unsquared( + const linestring_t &way, + double min_angle, + double max_angle +) { + const int num_points = boost::geometry::num_points(way); + for(int i = 0; i < num_points - 1; i++) { + // Three points + int a,b,c; + if (i < num_points - 3) { + a = i; + b = i + 1; + c = i + 2; + } else if (i == num_points - 3) { + a = i; + b = i + 1; + c = 0; + } else { + a = i; + b = 0; + c = 1; + } + double x1 = boost::geometry::get<0>(way[a]); + double y1 = boost::geometry::get<1>(way[a]); + double x2 = boost::geometry::get<0>(way[b]); + double y2 = boost::geometry::get<1>(way[b]); + double x3 = boost::geometry::get<0>(way[c]); + double y3 = boost::geometry::get<1>(way[c]); + + double angle = geo::Geo::calculateAngle(x1,y1,x2,y2,x3,y3); + + if ( + (angle > max_angle || angle < min_angle) && + (angle < 179 || angle > 181) + ) { + return true; + } + } + return false; +}; + +}; // namespace geospatial + +#endif // EOF __SEMANTIC_H__ + +// Local Variables: +// mode: C++ +// indent-tabs-mode: nil +// End: diff --git a/src/validate/geospatial.hh b/src/validate/geospatial.hh new file mode 100644 index 00000000..58a7c4ad --- /dev/null +++ b/src/validate/geospatial.hh @@ -0,0 +1,93 @@ +// +// Copyright (c) 2020, 2021, 2022, 2023 Humanitarian OpenStreetMap Team +// +// This file is part of Underpass. +// +// Underpass is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Underpass is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Underpass. If not, see . +// + +/// \file geospatial.hh +/// \brief This file implements the data validation used by HOT + +#ifndef __GEOSPATIAL_HH__ +#define __GEOSPATIAL_HH__ + +// This is generated by autoconf +#ifdef HAVE_CONFIG_H +# include "unconfig.h" +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +using namespace boost::posix_time; +using namespace boost::gregorian; + +#include "utils/yaml.hh" + +// MinGW related workaround +#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION + +#include "validate.hh" + +/// \namespace geospatial +namespace geospatial { + +/// \class Geospatial +/// \brief This is the plugin class, deprived from the Validate class +class Geospatial : public Validate +{ +public: + Geospatial(void); + ~Geospatial(void) { }; + + /// Check a POI for tags. A node that is part of a way shouldn't have any + /// tags, this is to check actual POIs, like a school. + std::shared_ptr checkPOI(const osmobjects::OsmNode &node, const std::string &type); + + /// This checks a way. A way should always have some tags. Often a polygon + /// is a building + std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type); + + // Factory method + static std::shared_ptr create(void) { + return std::make_shared(); + }; +private: + std::map> tests; + bool unsquared(const linestring_t &way, double min_angle = 89, double max_angle = 91); + bool duplicate(const std::list> &allways, osmobjects::OsmWay &way); + bool overlaps(const std::list> &allways, osmobjects::OsmWay &way); +}; + +BOOST_DLL_ALIAS(Geospatial::create, create_plugin) + +} // EOF geospatial namespace + +#endif // EOF __GEOSPATIAL_HH__ + +// Local Variables: +// mode: C++ +// indent-tabs-mode: nil +// End: diff --git a/src/validate/hotosm.cc b/src/validate/semantic.cc similarity index 74% rename from src/validate/hotosm.cc rename to src/validate/semantic.cc index 37639837..057ac84e 100644 --- a/src/validate/hotosm.cc +++ b/src/validate/semantic.cc @@ -17,8 +17,8 @@ // along with Underpass. If not, see . // -#ifndef __HOTOSM_H__ -#define __HOTOSM_H__ +#ifndef __SEMANTIC_H__ +#define __SEMANTIC_H__ #include #include @@ -40,53 +40,26 @@ #include #include "utils/yaml.hh" -#include "hotosm.hh" +#include "semantic.hh" #include "validate.hh" #include "osm/osmchange.hh" #include "utils/log.hh" using namespace logger; -namespace hotosm { +// This plugin checks for issues with tags +// [*] Required tags +// [*] Bad values +// [*] Empty value +// [*] No tags -LogFile &dbglogfile = LogFile::getDefaultInstance(); - -// FIXME: things to look for -// Villages, hamlets, neigborhoods, towns, or cities added without a name +namespace semantic { -Hotosm::Hotosm(void) {} +LogFile &dbglogfile = LogFile::getDefaultInstance(); -#if 0 -Hotosm::Hotosm(std::vector> &changes) -{ - for (auto it = std::begin(changes); it != std::end(changes); ++it) { - osmchange::OsmChange *change = it->get(); - change->dump(); - if (change->action == osmobjects::create) { - for (auto it = std::begin(change->nodes); it != std::end(change->nodes); ++it) { - osmobjects::OsmNode *node = it->get(); - if (node->tags.size() > 0) { - // log_debug("Validating New Node ID %1% has tags", node->id); - checkPOI(node); - } else { - continue; - } - // for (auto it = std::begin(change->ways); it != std::end(change->ways); ++it) { - // OsmWay *way = it->get(); - // if (way->tags.size() == 0) { - // log_error("Validating New Way ID %1% has no tags", way->id); - // checkWay(way); - // } else { - // continue; - // } - // } - } - } - } -} -#endif +Semantic::Semantic(void) {} -bool Hotosm::isValidTag(const std::string &key, const std::string &value, yaml::Node tags) { +bool Semantic::isValidTag(const std::string &key, const std::string &value, yaml::Node tags) { if (tags.contains_value(key, value) || (tags.get(key).children.size() == 0 && tags.contains_key(key))) { return true; @@ -95,7 +68,7 @@ bool Hotosm::isValidTag(const std::string &key, const std::string &value, yaml:: return false; } -bool Hotosm::isRequiredTag(const std::string &key, yaml::Node required_tags) { +bool Semantic::isRequiredTag(const std::string &key, yaml::Node required_tags) { if (required_tags.children.size() > 0 && required_tags.contains_key(key)) { log_debug("Required tag: %1%", key); return true; @@ -106,7 +79,7 @@ bool Hotosm::isRequiredTag(const std::string &key, yaml::Node required_tags) { // Check a POI for tags. A node that is part of a way shouldn't have any // tags, this is to check actual POIs, like a school. std::shared_ptr -Hotosm::checkPOI(const osmobjects::OsmNode &node, const std::string &type) +Semantic::checkPOI(const osmobjects::OsmNode &node, const std::string &type) { auto status = std::make_shared(node); status->timestamp = boost::posix_time::microsec_clock::universal_time(); @@ -128,11 +101,10 @@ Hotosm::checkPOI(const osmobjects::OsmNode &node, const std::string &type) yaml::Yaml tests = yamls[type]; // List of valid tags to be validated auto tags = tests.get("tags"); -#if 0 + // Not using required_tags disables writing features flagged for not being tag complete // from being written to the database thus reducing the size of the results. auto required_tags = tests.get("required_tags"); -#endif std::string key; int tagexists = 0; @@ -143,14 +115,12 @@ Hotosm::checkPOI(const osmobjects::OsmNode &node, const std::string &type) status->status.insert(badvalue); status->values.insert(vit->first + "=" + vit->second); } -#if 0 if (isRequiredTag(vit->first, required_tags)) { tagexists++; } -#endif + checkTag(vit->first, vit->second); } -#if 0 if (tagexists == required_tags.children.size()) { status->status.insert(complete); } else { @@ -159,14 +129,13 @@ Hotosm::checkPOI(const osmobjects::OsmNode &node, const std::string &type) if (status->status.size() == 0) { status->status.insert(correct); } -#endif return status; } // This checks a way. A way should always have some tags. Often a polygon // with no tags is a building. std::shared_ptr -Hotosm::checkWay(const osmobjects::OsmWay &way, const std::string &type) +Semantic::checkWay(const osmobjects::OsmWay &way, const std::string &type) { // On non-english numeric locales using decimal separator different than '.' // this is necessary to parse double strings with std::stod correctly @@ -189,59 +158,51 @@ Hotosm::checkWay(const osmobjects::OsmWay &way, const std::string &type) if (way.action == osmobjects::remove) { return status; } - if (way.linestring.size() == 0) { - return status; - } yaml::Yaml tests = yamls[type]; std::string key; - int tagexists = 0; // List of valid tags to be validated auto tags = tests.get("tags"); -#if 0 + + // These values are in the config section of the YAML file + auto config = tests.get("config"); + // Not using required_tags disables writing features flagged for not being tag complete // from being written to the database thus reducing the size of the results. auto required_tags = tests.get("required_tags"); -#endif - // These values are in the config section of the YAML file - auto config = tests.get("config"); // This enables/disables writing features flagged for not having values // in range as defined in the YAML config file. This prevents those // from being written to the database to reduce the size of the results. - bool values = tests.get("config").contains_value("values", "yes"); + int tagexists = 0; for (auto vit = std::begin(way.tags); vit != std::end(way.tags); ++vit) { - - if (!isValidTag(vit->first, vit->second, tags)) { - status->status.insert(badvalue); - status->values.insert(vit->first + "=" + vit->second); - } -#if 0 - if (isRequiredTag(vit->first, required_tags)) { - tagexists++; - } -#endif + if (!isValidTag(vit->first, vit->second, tags)) { + status->status.insert(badvalue); + status->values.insert(vit->first + "=" + vit->second); + } + if (isRequiredTag(vit->first, required_tags)) { + tagexists++; + } + checkTag(vit->first, vit->second); } -#if 0 + if (tagexists == required_tags.children.size()) { status->status.insert(complete); } else { status->status.insert(incomplete); } -#endif + return status; } // Check a tag for typical errors std::shared_ptr -Hotosm::checkTag(const std::string &key, const std::string &value) +Semantic::checkTag(const std::string &key, const std::string &value) { auto status = std::make_shared(); - - // log_trace("Hotosm::checkTag(%1%, %2%)", key, value); - // status->status.insert(correct); + // log_trace("Semantic::checkTag(%1%, %2%)", key, value); // Check for an empty value if (!key.empty() && value.empty()) { log_debug("WARNING: empty value for tag \"%1%\"", key); @@ -262,16 +223,12 @@ Hotosm::checkTag(const std::string &key, const std::string &value) log_error("WARNING: double quote in tag value \"%1%\"", value); status->status.insert(badvalue); } - - if (status->status.size() == 0) { - // status->status.insert(correct); - } return status; } // Check a OSM Change for typical errors std::vector -Hotosm::checkOsmChange(const std::string &xml, const std::string &check) { +Semantic::checkOsmChange(const std::string &xml, const std::string &check) { osmchange::OsmChangeFile ocf; std::stringstream _xml(xml); ocf.readXML(_xml); @@ -298,9 +255,9 @@ Hotosm::checkOsmChange(const std::string &xml, const std::string &check) { return result; } -}; // namespace hotosm +}; // namespace semantic -#endif // EOF __HOTOSM_H__ +#endif // EOF __SEMANTIC_H__ // Local Variables: // mode: C++ diff --git a/src/validate/hotosm.hh b/src/validate/semantic.hh similarity index 86% rename from src/validate/hotosm.hh rename to src/validate/semantic.hh index 0da595e3..6f62896c 100644 --- a/src/validate/hotosm.hh +++ b/src/validate/semantic.hh @@ -17,11 +17,11 @@ // along with Underpass. If not, see . // -/// \file hotosm.hh +/// \file semantic.hh /// \brief This file implements the data validation used by HOT -#ifndef __HOTOSM_HH__ -#define __HOTOSM_HH__ +#ifndef __SEMANTIC_HH__ +#define __SEMANTIC_HH__ // This is generated by autoconf #ifdef HAVE_CONFIG_H @@ -51,16 +51,16 @@ using namespace boost::gregorian; #include "validate.hh" -/// \namespace hotosm -namespace hotosm { +/// \namespace semantic +namespace semantic { -/// \class Hotosm +/// \class Semantic /// \brief This is the plugin class, deprived from the Validate class -class Hotosm : public Validate +class Semantic : public Validate { public: - Hotosm(void); - ~Hotosm(void) { }; + Semantic(void); + ~Semantic(void) { }; /// Check a POI for tags. A node that is part of a way shouldn't have any /// tags, this is to check actual POIs, like a school. @@ -77,8 +77,8 @@ public: std::vector checkOsmChange(const std::string &xml, const std::string &check); // Factory method - static std::shared_ptr create(void) { - return std::make_shared(); + static std::shared_ptr create(void) { + return std::make_shared(); }; private: std::map> tests; @@ -86,11 +86,11 @@ private: bool isRequiredTag(const std::string &key, yaml::Node required_tags); }; -BOOST_DLL_ALIAS(Hotosm::create, create_plugin) +BOOST_DLL_ALIAS(Semantic::create, create_plugin) -} // EOF hotosm namespace +} // EOF semantic namespace -#endif // EOF __HOTOSM_HH__ +#endif // EOF __SEMANTIC_HH__ // Local Variables: // mode: C++ diff --git a/src/validate/validate.hh b/src/validate/validate.hh index 5ec3788a..5d5cdf12 100644 --- a/src/validate/validate.hh +++ b/src/validate/validate.hh @@ -57,7 +57,7 @@ using namespace logger; // JOSM validator // [ ] Crossing ways -// [/] Duplicate Ways +// [ ] Duplicate Ways // [ ] Duplicate nodes // [ ] Duplicate relations // [ ] Duplicated way nodes @@ -65,18 +65,18 @@ using namespace logger; // [x] No square building corners // OSMInspector -// [x] Empty tag key -// [x] Unknown highway type +// [ ] Empty tag key +// [ ] Unknown highway type // [ ] Single node way // [ ] Interescting ways // OSMose -// [/] Overlapping buildings +// [ ] Overlapping buildings // [ ] orphan nodes -// [/] Duplicate geomtry +// [ ] Duplicate geomtry // [ ] Highway not connected -// [x] Missing tags -// [/] Duplicate object +// [ ] Missing tags +// [ ] Duplicate object /// \enum valerror_t /// The data validation values for the status column in the database. @@ -173,6 +173,10 @@ class BOOST_SYMBOL_VISIBLE Validate { Validate(void) { std::string path = PKGLIBDIR; path += "/config/validate"; + loadConfig(path); + } + + void loadConfig(const std::string &path) { if (!boost::filesystem::exists(path)) { throw std::runtime_error("Validation configuration file not found: " + path); } @@ -187,35 +191,31 @@ class BOOST_SYMBOL_VISIBLE Validate { } } } -#if 0 - Validate(const std::string &filespec) { - yaml::Yaml yaml; - yaml.read(filespec); - if (!config.stem().empty()) { - yamls[config.stem()] = yaml; - } } -#endif - }; + virtual ~Validate(void){}; // Validate(std::vector> &changes) {}; /// Check a POI for tags. A node that is part of a way shouldn't have any /// tags, this is to check actual POIs, like a school. - virtual std::shared_ptr checkPOI(const osmobjects::OsmNode &node, const std::string &type) = 0; - + virtual std::shared_ptr checkGeometry(const osmobjects::OsmNode &node, const std::string &type) = 0; /// This checks a way. A way should always have some tags. Often a polygon /// is a building - virtual std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type) = 0; - std::shared_ptr checkTags(std::map tags) { - auto status = std::make_shared(); - for (auto it = std::begin(tags); it != std::end(tags); ++it) { - // FIXME: temporarily disabled - // result = checkTag(it->first, it->second); - } - return status; - }; - virtual std::shared_ptr checkTag(const std::string &key, const std::string &value) = 0; + virtual std::shared_ptr checkGeometry(const osmobjects::OsmWay &way, const std::string &type) = 0; + + virtual std::shared_ptr checkSemantic(const osmobjects::OsmWay &way, const std::string &type) = 0; + virtual std::shared_ptr checkSemantic(const osmobjects::OsmWay &node, const std::string &type) = 0; + + std::shared_ptr checkNode(const osmobjects::OsmWay &node, const std::string &type) { + auto status = std::make_shared(node); + auto geometryStatus = checkGeometry(node, type); + auto semanticStatus = checkSemantic(node, type); + } + std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type) { + // checkGeometry + // checkSemantic + } + yaml::Yaml &operator[](const std::string &key) { return yamls[key]; }; void dump(void) { @@ -224,103 +224,6 @@ class BOOST_SYMBOL_VISIBLE Validate { } } - bool overlaps(const std::list> &allways, osmobjects::OsmWay &way) { - // This test only applies to buildings, as highways often overlap. - // TODO: move logic to a config file - yaml::Yaml tests = yamls["building"]; - if (tests.get("config").contains_value("overlaps", "yes")) { -#ifdef TIMING_DEBUG_X - boost::timer::auto_cpu_timer timer("validate::overlaps: took %w seconds\n"); -#endif - if (way.numPoints() <= 1) { - return false; - } - for (auto nit = std::begin(allways); nit != std::end(allways); ++nit) { - osmobjects::OsmWay *oldway = nit->get(); - if (boost::geometry::overlaps(oldway->polygon, way.polygon)) { - if (way.getTagValue("layer") == oldway->getTagValue("layer") && way.id != oldway->id) { - log_error("Building %1% overlaps with %2%", way.id, oldway->id); - return true; - } - } - } - } - return false; - } - - bool duplicate(const std::list> &allways, osmobjects::OsmWay &way) { - // This test only applies to buildings, as highways often overlap. - // TODO: move logic to a config file - yaml::Yaml tests = yamls["building"]; - if (tests.get("config").contains_value("duplicate", "yes")) { -#ifdef TIMING_DEBUG_X - boost::timer::auto_cpu_timer timer("validate::duplicate: took %w seconds\n"); -#endif - if (way.numPoints() <= 1) { - return false; - } - - for (auto nit = std::begin(allways); nit != std::end(allways); ++nit) { - osmobjects::OsmWay *oldway = nit->get(); - std::deque output; - bg::intersection(oldway->polygon, way.polygon, output); - double iarea = 0; - for (auto& p : output) - iarea += bg::area(p); - double wayarea = bg::area(way.polygon); - double iareapercent = (iarea * 100) / wayarea; - if (iareapercent >= 80) { - if (way.getTagValue("layer") == oldway->getTagValue("layer") && way.id != oldway->id) { - log_error("Building %1% duplicate %2%", way.id, oldway->id); - return true; - } - } - } - } - return false; - } - - bool unsquared( - const linestring_t &way, - double min_angle = 89, - double max_angle = 91 - ) { - const int num_points = boost::geometry::num_points(way); - for(int i = 0; i < num_points - 1; i++) { - // Three points - int a,b,c; - if (i < num_points - 3) { - a = i; - b = i + 1; - c = i + 2; - } else if (i == num_points - 3) { - a = i; - b = i + 1; - c = 0; - } else { - a = i; - b = 0; - c = 1; - } - double x1 = boost::geometry::get<0>(way[a]); - double y1 = boost::geometry::get<1>(way[a]); - double x2 = boost::geometry::get<0>(way[b]); - double y2 = boost::geometry::get<1>(way[b]); - double x3 = boost::geometry::get<0>(way[c]); - double y3 = boost::geometry::get<1>(way[c]); - - double angle = geo::Geo::calculateAngle(x1,y1,x2,y2,x3,y3); - - if ( - (angle > max_angle || angle < min_angle) && - (angle < 179 || angle > 181) - ) { - return true; - } - } - return false; - }; - protected: std::map yamls; }; From 3669a88e1f3fa4d09ddb458462b91c077e1a39c1 Mon Sep 17 00:00:00 2001 From: Emillio Mariscal Date: Tue, 7 Nov 2023 20:41:02 -0300 Subject: [PATCH 2/4] Big refactor, fixes for tests --- src/bootstrap/bootstrap.cc | 22 +- src/data/pq.cc | 21 +- src/osm/osmchange.cc | 50 +- src/osm/osmchange.hh | 2 + src/raw/queryraw.cc | 6 +- src/replicator/threads.cc | 2 +- src/testsuite/libunderpass.all/Makefile | 1084 ----------------- src/testsuite/libunderpass.all/Makefile.am | 9 +- src/testsuite/libunderpass.all/hotosm-test.cc | 157 --- src/testsuite/libunderpass.all/pq-test.cc | 2 +- src/testsuite/libunderpass.all/val-test.cc | 182 ++- .../libunderpass.all/val-unsquared-test.cc | 5 +- src/testsuite/testdata/stats/test_stats.yaml | 2 +- src/testsuite/testdata/validation/rect.osc | 223 +++- src/utils/yaml.cc | 3 +- src/validate/Makefile.am | 4 +- src/validate/defaultvalidation.cc | 85 ++ src/validate/defaultvalidation.hh | 75 ++ src/validate/geospatial.cc | 138 ++- src/validate/geospatial.hh | 51 +- src/validate/semantic.cc | 144 +-- src/validate/semantic.hh | 39 +- src/validate/validate.hh | 23 +- src/wrappers/python.cc | 64 +- 24 files changed, 689 insertions(+), 1704 deletions(-) delete mode 100644 src/testsuite/libunderpass.all/Makefile delete mode 100644 src/testsuite/libunderpass.all/hotosm-test.cc create mode 100644 src/validate/defaultvalidation.cc create mode 100644 src/validate/defaultvalidation.hh diff --git a/src/bootstrap/bootstrap.cc b/src/bootstrap/bootstrap.cc index 1a8f6e3d..0b8699df 100644 --- a/src/bootstrap/bootstrap.cc +++ b/src/bootstrap/bootstrap.cc @@ -60,7 +60,7 @@ void startProcessingWays(const underpassconfig::UnderpassConfig &config) { boost::function creator; try { creator = boost::dll::import_alias(lib_path / "libunderpass.so", "create_plugin", boost::dll::load_mode::append_decorations); - log_debug("Loaded plugin hotosm!"); + log_debug("Loaded plugin!"); } catch (std::exception &e) { log_debug("Couldn't load plugin! %1%", e.what()); exit(0); @@ -77,7 +77,7 @@ void startProcessingWays(const underpassconfig::UnderpassConfig &config) { for (auto table_it = tables.begin(); table_it != tables.end(); ++table_it) { std::cout << "Counting geometries ... " << std::endl; int total = queryraw->getWaysCount(*table_it); - std::cout << "Total ways:" << total << std::endl; + std::cout << "Total: " << total << std::endl; if (total > 0) { int count = 0; long lastid = 0; @@ -126,22 +126,10 @@ processWays(WayTask &wayTask, const std::string &tableName, const underpassconfi if (wayTask.processed > 0) { // Proccesing ways for (auto way = ways->begin(); way != ways->end(); ++way) { - // If it's closed polygon - if (way->isClosed()) { - log_debug("Way Id: %1%", way->id); - - // Bad geometry - if (way->containsKey("building") && (boost::geometry::num_points(way->linestring) - 1 < 4 || - plugin->unsquared(way->linestring)) - ) { - auto status = ValidateStatus(*way); - status.timestamp = boost::posix_time::microsec_clock::universal_time(); - status.source = "building"; - boost::geometry::centroid(way->linestring, status.center); - task->query += queryvalidate->applyChange(status, badgeom); - } + auto status = plugin->checkWay(*way, "building"); + for (auto status_it = status->status.begin(); status_it != status->status.end(); ++status_it) { + task->query += queryvalidate->applyChange(*status, *status_it); } - // Fill the way_refs table if (!config.norefs) { for (auto ref = way->refs.begin(); ref != way->refs.end(); ++ref) { diff --git a/src/data/pq.cc b/src/data/pq.cc index 678bcd8e..7018e815 100644 --- a/src/data/pq.cc +++ b/src/data/pq.cc @@ -25,7 +25,8 @@ #include "data/pq.hh" #include #include -#include +#include +#include #include #include #include @@ -152,11 +153,24 @@ Pq::query(const std::string &query) { std::scoped_lock write_lock{pqxx_mutex}; pqxx::work worker(*sdb); - pqxx::result result = worker.exec(query); + auto result = worker.exec(query); worker.commit(); return result; } +std::string Latin1ToUTF8(const std::string& latin1str) { + std::string utf8str; + for (char c : latin1str) { + if (static_cast(c) <= 0x7F) { + utf8str.push_back(c); + } else { + utf8str.push_back(0xC0 | static_cast(c) >> 6); + utf8str.push_back(0x80 | (static_cast(c) & 0x3F)); + } + } + return utf8str; +} + std::string Pq::escapedString(std::string text) { @@ -180,7 +194,8 @@ Pq::escapedString(std::string text) } i++; } - return sdb->esc(newstr); + + return sdb->esc(Latin1ToUTF8(newstr)); } } // namespace pq diff --git a/src/osm/osmchange.cc b/src/osm/osmchange.cc index 8f86593c..0a064878 100644 --- a/src/osm/osmchange.cc +++ b/src/osm/osmchange.cc @@ -130,6 +130,19 @@ OsmChangeFile::readChanges(const std::string &file) return true; } +void +OsmChangeFile::buildGeometriesFromNodeCache() { + for (auto it = std::begin(changes); it != std::end(changes); ++it) { + osmchange::OsmChange *change = it->get(); + for (auto wit = std::begin(change->ways); wit != std::end(change->ways); ++wit) { + osmobjects::OsmWay *way = wit->get(); + for (auto lit = std::begin(way->refs); lit != std::end(way->refs); ++lit) { + boost::geometry::append(way->linestring, nodecache[*lit]); + } + } + } +} + bool OsmChangeFile::readXML(std::istream &xml) { @@ -699,10 +712,7 @@ OsmChangeFile::validateNodes(const multipolygon_t &poly, std::shared_ptr node_tests = {"building", "natural", "place", "waterway"}; for (auto test_it = std::begin(node_tests); test_it != std::end(node_tests); ++test_it) { if (node->containsKey(*test_it)) { - auto status = plugin->checkPOI(*node, *test_it); - if (status->status.size() > 0) { - status->center = node->point; - } + auto status = plugin->checkNode(*node, *test_it); totals->push_back(status); } } @@ -725,38 +735,8 @@ OsmChangeFile::validateWays(const multipolygon_t &poly, std::shared_ptrpriority) { continue; } - - // Geometry checks - auto status = std::make_shared(*way); - if (way->containsKey("building")) { - // See if the way is a closed polygon - if (way->refs.front() == way->refs.back()) { - status->timestamp = boost::posix_time::microsec_clock::universal_time(); - status->uid = way->uid; - // Bad geometry - if (boost::geometry::num_points(way->linestring) - 1 < 4 || - plugin->unsquared(way->linestring) - ) { - status->status.insert(badgeom); - } - if (status->status.size() > 0) { - status->source = "building"; - boost::geometry::centroid(way->linestring, status->center); - } - } - } + auto status = plugin->checkWay(*way, "building"); totals->push_back(status); - - // Semantic checks - std::vector way_tests = {"building"}; - for (auto test_it = way_tests.begin(); test_it != way_tests.end(); ++test_it) { - if (way->containsKey(*test_it)) { - auto status = plugin->checkWay(*way, *test_it); - status->source = *test_it; - // boost::geometry::centroid(way->linestring, status->center); - totals->push_back(status); - } - } } } return totals; diff --git a/src/osm/osmchange.hh b/src/osm/osmchange.hh index e66c4984..d04defc8 100644 --- a/src/osm/osmchange.hh +++ b/src/osm/osmchange.hh @@ -245,6 +245,8 @@ class OsmChangeFile /// Delete any data not in the boundary polygon void areaFilter(const multipolygon_t &poly); + void buildGeometriesFromNodeCache(); + #ifdef LIBXML /// Called by libxml++ for each element of the XML file void on_start_element(const Glib::ustring &name, diff --git a/src/raw/queryraw.cc b/src/raw/queryraw.cc index 38bdd8a4..bd156173 100644 --- a/src/raw/queryraw.cc +++ b/src/raw/queryraw.cc @@ -368,13 +368,13 @@ QueryRaw::getNodeCacheFromWays(std::shared_ptr> ways, std::m } } -std::map parseTagsString(const std::string& input) { +std::map parseTagsString(std::string input) { + input.pop_back(); std::map result; std::stringstream ss(input); std::string token; while (std::getline(ss, token, ',')) { - // Find the position of the arrow - size_t arrowPos = token.find(":"); + size_t arrowPos = token.find_last_of(":"); if (arrowPos != std::string::npos) { std::string key = token.substr(1, arrowPos - 1); std::string value = token.substr(arrowPos + 2); diff --git a/src/replicator/threads.cc b/src/replicator/threads.cc index f0790845..f756caeb 100644 --- a/src/replicator/threads.cc +++ b/src/replicator/threads.cc @@ -248,7 +248,7 @@ startMonitorChanges(std::shared_ptr &remote, boost::function creator; try { creator = boost::dll::import_alias(lib_path / "libunderpass.so", "create_plugin", boost::dll::load_mode::append_decorations); - log_debug("Loaded plugin hotosm!"); + log_debug("Loaded plugin!"); } catch (std::exception &e) { log_debug("Couldn't load plugin! %1%", e.what()); exit(0); diff --git a/src/testsuite/libunderpass.all/Makefile b/src/testsuite/libunderpass.all/Makefile deleted file mode 100644 index 493f8d11..00000000 --- a/src/testsuite/libunderpass.all/Makefile +++ /dev/null @@ -1,1084 +0,0 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. -# src/testsuite/libunderpass.all/Makefile. Generated from Makefile.in by configure. - -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - - -# -# Copyright (c) 2020, 2021, 2022, 2023 Humanitarian OpenStreetMap Team -# -# This file is part of Underpass. -# -# Underpass is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Underpass is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Underpass. If not, see . -# - -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/underpass -pkgincludedir = $(includedir)/underpass -pkglibdir = $(libdir)/underpass -pkglibexecdir = $(libexecdir)/underpass -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = x86_64-pc-linux-gnu -host_triplet = x86_64-pc-linux-gnu -check_PROGRAMS = pq-test$(EXEEXT) change-test$(EXEEXT) \ - yaml-test$(EXEEXT) statsconfig-test$(EXEEXT) \ - planetreplicator-test$(EXEEXT) geo-test$(EXEEXT) \ - areafilter-test$(EXEEXT) hashtags-test$(EXEEXT) \ - stats-test$(EXEEXT) val-test$(EXEEXT) test-playground$(EXEEXT) -subdir = src/testsuite/libunderpass.all -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_base.m4 \ - $(top_srcdir)/m4/ax_boost_date_time.m4 \ - $(top_srcdir)/m4/ax_boost_filesystem.m4 \ - $(top_srcdir)/m4/ax_boost_iostreams.m4 \ - $(top_srcdir)/m4/ax_boost_locale.m4 \ - $(top_srcdir)/m4/ax_boost_log.m4 \ - $(top_srcdir)/m4/ax_boost_program_options.m4 \ - $(top_srcdir)/m4/ax_boost_python.m4 \ - $(top_srcdir)/m4/ax_boost_serialization.m4 \ - $(top_srcdir)/m4/ax_boost_system.m4 \ - $(top_srcdir)/m4/ax_boost_thread.m4 \ - $(top_srcdir)/m4/ax_boost_timer.m4 \ - $(top_srcdir)/m4/ax_python_devel.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/host-cpu-c-abi.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/unconfig.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am_areafilter_test_OBJECTS = areafilter-test.$(OBJEXT) -areafilter_test_OBJECTS = $(am_areafilter_test_OBJECTS) -am__DEPENDENCIES_1 = -am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -areafilter_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) -am__v_lt_0 = --silent -am__v_lt_1 = -areafilter_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(AM_CXXFLAGS) $(CXXFLAGS) $(areafilter_test_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_change_test_OBJECTS = change_test-change-test.$(OBJEXT) -change_test_OBJECTS = $(am_change_test_OBJECTS) -change_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -change_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(change_test_LDFLAGS) $(LDFLAGS) -o $@ -am_geo_test_OBJECTS = geo_test-geo-test.$(OBJEXT) -geo_test_OBJECTS = $(am_geo_test_OBJECTS) -geo_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -geo_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(geo_test_LDFLAGS) $(LDFLAGS) -o $@ -am_hashtags_test_OBJECTS = hashtags-test.$(OBJEXT) -hashtags_test_OBJECTS = $(am_hashtags_test_OBJECTS) -hashtags_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -hashtags_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(AM_CXXFLAGS) $(CXXFLAGS) $(hashtags_test_LDFLAGS) $(LDFLAGS) \ - -o $@ -am_planetreplicator_test_OBJECTS = planetreplicator-test.$(OBJEXT) -planetreplicator_test_OBJECTS = $(am_planetreplicator_test_OBJECTS) -planetreplicator_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -planetreplicator_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(AM_CXXFLAGS) $(CXXFLAGS) $(planetreplicator_test_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_pq_test_OBJECTS = pq_test-pq-test.$(OBJEXT) -pq_test_OBJECTS = $(am_pq_test_OBJECTS) -pq_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -pq_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(pq_test_LDFLAGS) $(LDFLAGS) -o $@ -am_stats_test_OBJECTS = stats_test-stats-test.$(OBJEXT) -stats_test_OBJECTS = $(am_stats_test_OBJECTS) -stats_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -stats_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(stats_test_LDFLAGS) $(LDFLAGS) -o $@ -am_statsconfig_test_OBJECTS = statsconfig-test.$(OBJEXT) -statsconfig_test_OBJECTS = $(am_statsconfig_test_OBJECTS) -statsconfig_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -statsconfig_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(AM_CXXFLAGS) $(CXXFLAGS) $(statsconfig_test_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_test_playground_OBJECTS = test-playground.$(OBJEXT) -test_playground_OBJECTS = $(am_test_playground_OBJECTS) -test_playground_DEPENDENCIES = $(am__DEPENDENCIES_2) -test_playground_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ - $(AM_CXXFLAGS) $(CXXFLAGS) $(test_playground_LDFLAGS) \ - $(LDFLAGS) -o $@ -am_val_test_OBJECTS = val_test-val-test.$(OBJEXT) -val_test_OBJECTS = $(am_val_test_OBJECTS) -val_test_DEPENDENCIES = $(am__DEPENDENCIES_2) ../../validate/hotosm.lo -val_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(val_test_LDFLAGS) $(LDFLAGS) -o $@ -am_yaml_test_OBJECTS = yaml_test-yaml-test.$(OBJEXT) -yaml_test_OBJECTS = $(am_yaml_test_OBJECTS) -yaml_test_DEPENDENCIES = $(am__DEPENDENCIES_2) -yaml_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(yaml_test_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_P = $(am__v_P_$(V)) -am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY)) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I. -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/areafilter-test.Po \ - ./$(DEPDIR)/change_test-change-test.Po \ - ./$(DEPDIR)/geo_test-geo-test.Po ./$(DEPDIR)/hashtags-test.Po \ - ./$(DEPDIR)/planetreplicator-test.Po \ - ./$(DEPDIR)/pq_test-pq-test.Po \ - ./$(DEPDIR)/stats_test-stats-test.Po \ - ./$(DEPDIR)/statsconfig-test.Po ./$(DEPDIR)/test-playground.Po \ - ./$(DEPDIR)/val_test-val-test.Po \ - ./$(DEPDIR)/yaml_test-yaml-test.Po -am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_$(V)) -am__v_CXX_ = $(am__v_CXX_$(AM_DEFAULT_VERBOSITY)) -am__v_CXX_0 = @echo " CXX " $@; -am__v_CXX_1 = -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CXXLD = $(am__v_CXXLD_$(V)) -am__v_CXXLD_ = $(am__v_CXXLD_$(AM_DEFAULT_VERBOSITY)) -am__v_CXXLD_0 = @echo " CXXLD " $@; -am__v_CXXLD_1 = -SOURCES = $(areafilter_test_SOURCES) $(change_test_SOURCES) \ - $(geo_test_SOURCES) $(hashtags_test_SOURCES) \ - $(planetreplicator_test_SOURCES) $(pq_test_SOURCES) \ - $(stats_test_SOURCES) $(statsconfig_test_SOURCES) \ - $(test_playground_SOURCES) $(val_test_SOURCES) \ - $(yaml_test_SOURCES) -DIST_SOURCES = $(areafilter_test_SOURCES) $(change_test_SOURCES) \ - $(geo_test_SOURCES) $(hashtags_test_SOURCES) \ - $(planetreplicator_test_SOURCES) $(pq_test_SOURCES) \ - $(stats_test_SOURCES) $(statsconfig_test_SOURCES) \ - $(test_playground_SOURCES) $(val_test_SOURCES) \ - $(yaml_test_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DEJATOOL = $(PACKAGE) -RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir -EXPECT = expect -RUNTEST = runtest -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = ${SHELL} /code/missing aclocal-1.16 -AMTAR = $${TAR-tar} -AM_DEFAULT_VERBOSITY = 1 -AR = ar -ARCH = x86_64 -AUTOCONF = ${SHELL} /code/missing autoconf -AUTOHEADER = ${SHELL} /code/missing autoheader -AUTOMAKE = ${SHELL} /code/missing automake-1.16 -AWK = mawk -BOOST_CPPFLAGS = -pthread -I/usr/include -BOOST_DATE_TIME_LIB = -lboost_date_time -BOOST_FILESYSTEM_LIB = -lboost_filesystem -BOOST_IOSTREAMS_LIB = -lboost_iostreams -BOOST_LDFLAGS = -L/usr/lib/x86_64-linux-gnu -BOOST_LOCALE_LIB = -lboost_locale -BOOST_LOG_LIB = -lboost_log -BOOST_PROGRAM_OPTIONS_LIB = -lboost_program_options -BOOST_PYTHON_LIB = -BOOST_SERIALIZATION_LIB = -lboost_serialization -BOOST_SYSTEM_LIB = -lboost_system -BOOST_THREAD_LIB = -lboost_thread -lpthread -BOOST_TIMER_LIB = -lboost_timer -CC = gcc -CCDEPMODE = depmode=gcc3 -CFLAGS = -g -O2 -CPP = gcc -E -CPPFLAGS = -I/usr/local/include -I/usr/include/gdal -pthread -I/usr/lib/x86_64-linux-gnu/openmpi/include -I/usr/lib/x86_64-linux-gnu/openmpi/include/openmpi -I/usr/include/python3.8 -I/usr/include/x86_64-linux-gnu/python3.8 -I/usr/include/libxml++-2.6 -I/usr/lib/x86_64-linux-gnu/libxml++-2.6/include -I/usr/include/libxml2 -I/usr/include/glibmm-2.4 -I/usr/lib/x86_64-linux-gnu/glibmm-2.4/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/sigc++-2.0 -I/usr/lib/x86_64-linux-gnu/sigc++-2.0/include -I/usr/include/python3.8 -I/usr/include/python3.8 -Wno-unused-result -Wsign-compare -g -fdebug-prefix-map=/build/python3.8-4OrTnN/python3.8-3.8.10=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O3 -Wall -CXX = g++ -CXXCPP = g++ -E -CXXDEPMODE = depmode=gcc3 -CXXFLAGS = -g -O2 -std=c++17 -CYGPATH_W = echo -DEFS = -DHAVE_CONFIG_H -DEPDIR = .deps -DLLTOOL = false -DLOPEN = -dlopen -DLPREOPEN = -dlpreopen -DOXYGEN = -DSYMUTIL = -DUMPBIN = -ECHO_C = -ECHO_N = -n -ECHO_T = -EGREP = /usr/bin/grep -E -EXEEXT = -FGREP = /usr/bin/grep -F -GETTEXT_MACRO_VERSION = 0.20 -GIT = /usr/bin/git -GMSGFMT = : -GMSGFMT_015 = : -GREP = /usr/bin/grep -INSTALL = /usr/bin/install -c -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_PROGRAM = ${INSTALL} -INSTALL_SCRIPT = ${INSTALL} -INSTALL_STRIP_PROGRAM = $(install_sh) -c -s -INTLLIBS = -INTL_MACOSX_LIBS = -LD = /usr/bin/ld -m elf_x86_64 -LDFLAGS = -LIBICONV = -LIBINTL = -LIBOBJS = -LIBS = -lexpat -lz -L/usr/lib64 -lbz2 -L/usr/local/lib -lpqxx -lssl -lcrypto -lgumbo -lz -lgdal -L/usr/lib/x86_64-linux-gnu/openmpi/lib -lmpi -lxml++-2.6 -lxml2 -lglibmm-2.4 -lgobject-2.0 -lglib-2.0 -lsigc-2.0 -lpthread -ldl -lboost_regex -lcrypt -lpthread -ldl -lutil -lm -lm -lpython3.8 -LIBTOOL = $(SHELL) $(top_builddir)/libtool -LIPO = -LN_S = ln -s -LTLIBICONV = -LTLIBINTL = -LTLIBOBJS = -LT_SYS_LIBRARY_PATH = -MAKEINFO = ${SHELL} /code/missing makeinfo -MANIFEST_TOOL = : -MKDIR_P = /usr/bin/mkdir -p -MSGFMT = : -MSGMERGE = : -MSGMERGE_FOR_MSGFMT_OPTION = --no-location --quiet -NM = /usr/bin/nm -B -NMEDIT = -OBJDUMP = objdump -OBJEXT = o -OTOOL = -OTOOL64 = -PACKAGE = underpass -PACKAGE_BUGREPORT = -PACKAGE_NAME = underpass -PACKAGE_STRING = underpass 0.3_dev -PACKAGE_TARNAME = underpass -PACKAGE_URL = -PACKAGE_VERSION = 0.3_dev -PATH_SEPARATOR = : -PCH_FLAGS = -include all-includes.h -Winvalid-pch -POMAKEFILEDEPS = -POSUB = -PYTHON = /usr/bin/python -PYTHON_CPPFLAGS = -I/usr/include/python3.8 -PYTHON_EXEC_PREFIX = ${exec_prefix} -PYTHON_EXTRA_LDFLAGS = -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -PYTHON_EXTRA_LIBS = -lcrypt -lpthread -ldl -lutil -lm -lm -PYTHON_LIBS = -L/usr/lib -lpython3.8 -PYTHON_PLATFORM = linux -PYTHON_PLATFORM_SITE_PKG = -PYTHON_PREFIX = ${prefix} -PYTHON_SITE_PKG = /usr/lib/python3.8/site-packages -PYTHON_VERSION = 3.8 -RANLIB = ranlib -SED = /usr/bin/sed -SET_MAKE = -SHELL = /bin/bash -SRCDIR = . -STRIP = strip -USE_NLS = no -VERSION = 0.3_dev -XGETTEXT = : -XGETTEXT_015 = : -XGETTEXT_EXTRA_OPTIONS = -abs_builddir = /code/src/testsuite/libunderpass.all -abs_srcdir = /code/src/testsuite/libunderpass.all -abs_top_builddir = /code -abs_top_srcdir = /code -ac_ct_AR = ar -ac_ct_CC = gcc -ac_ct_CXX = g++ -ac_ct_DUMPBIN = -am__include = include -am__leading_dot = . -am__quote = -am__tar = $${TAR-tar} chof - "$$tardir" -am__untar = $${TAR-tar} xf - -bindir = ${exec_prefix}/bin -build = x86_64-pc-linux-gnu -build_alias = -build_cpu = x86_64 -build_os = linux-gnu -build_vendor = pc -builddir = . -datadir = ${datarootdir} -datarootdir = ${prefix}/share -docdir = ${datarootdir}/docs/${PACKAGE_TARNAME} -dvidir = ${docdir} -exec_prefix = ${prefix} -host = x86_64-pc-linux-gnu -host_alias = -host_cpu = x86_64 -host_os = linux-gnu -host_vendor = pc -htmldir = ${docdir} -includedir = ${prefix}/include -infodir = ${datarootdir}/info -install_sh = ${SHELL} /code/install-sh -libdir = ${exec_prefix}/lib -libexecdir = ${exec_prefix}/libexec -localedir = ${datarootdir}/locale -localstatedir = ${prefix}/var -mandir = ${datarootdir}/man -mkdir_p = $(MKDIR_P) -oldincludedir = /usr/include -pdfdir = ${docdir} -pkgpyexecdir = ${pyexecdir}/underpass -pkgpythondir = ${pythondir}/underpass -prefix = /usr/local -program_transform_name = s,x,x, -psdir = ${docdir} -pyexecdir = ${exec_prefix}/lib/python3.8/site-packages -pythondir = ${prefix}/lib/python3.8/site-packages -runstatedir = ${localstatedir}/run -sbindir = ${exec_prefix}/sbin -sharedstatedir = ${prefix}/com -srcdir = . -sysconfdir = ${prefix}/etc -target_alias = -top_build_prefix = ../../../ -top_builddir = ../../.. -top_srcdir = ../../.. -AUTOMAKE_OPTIONS = dejagnu -TOPSRC := $(shell cd $(top_srcdir) && pwd)/src -AM_CPPFLAGS = -I$(TOPSRC) -DDATADIR=\"$(TOPSRC)\" -AM_LDFLAGS = -L../.. -BOOST_LIBS = \ - $(BOOST_DATE_TIME_LIB) \ - $(BOOST_SYSTEM_LIB) \ - $(BOOST_FILESYSTEM_LIB) \ - $(BOOST_LOG_LIB) \ - $(BOOST_PROGRAM_OPTIONS_LIB) \ - $(BOOST_IOSTREAMS_LIB) \ - $(BOOST_THREAD_LIB) \ - $(BOOST_LOCALE_LIB) \ - $(BOOST_TIMER_LIB) \ - $(BOOST_PYTHON_LIB) - -AM_CXXFLAGS = \ - -fPIC \ - -DPKGLIBDIR=\"$(pkglibdir)\" \ - -DTOPSRCDIR=\"$(TOPSRC)\" \ - -DSRCDIR=\"$(srcdir)\" \ - -DBOOST_LOCALE_HIDE_AUTO_PTR \ - -Wno-deprecated-declarations - -yaml_test_SOURCES = yaml-test.cc -yaml_test_LDFLAGS = -L../.. -yaml_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -yaml_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) -pq_test_SOURCES = pq-test.cc -pq_test_LDFLAGS = -L../.. -pq_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -pq_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) -geo_test_SOURCES = geo-test.cc -geo_test_LDFLAGS = -L../.. -geo_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -geo_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) -val_test_SOURCES = val-test.cc -val_test_LDFLAGS = -L../.. -val_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -val_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) ../../validate/hotosm.lo - -# Test the replication classes -#replication_test_SOURCES = replication-test.cc -#replication_test_LDFLAGS = -L../.. -#rplication_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -#replication_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - -# Test the OSM DB classes -#hotosm_test_SOURCES = hotosm-test.cc -#hotosm_test_LDFLAGS = -L../.. -#hotosm_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - -# Test the OSM Stats class -stats_test_SOURCES = stats-test.cc -stats_test_LDFLAGS = -L../.. -stats_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -stats_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - -# Test the OSM StatsConfig -statsconfig_test_SOURCES = statsconfig-test.cc -statsconfig_test_LDFLAGS = -L../.. -statsconfig_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - -# Test the PlanetReplicator class -planetreplicator_test_SOURCES = planetreplicator-test.cc -planetreplicator_test_LDFLAGS = -L../.. -planetreplicator_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - -# Test the Changeset class -change_test_SOURCES = change-test.cc -change_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -change_test_LDFLAGS = -L../.. -change_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - -# Test areaFilter -areafilter_test_SOURCES = areafilter-test.cc -areafilter_test_LDFLAGS = -L../.. -areafilter_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - -# Hashtags test -hashtags_test_SOURCES = hashtags-test.cc -hashtags_test_LDFLAGS = -L../.. -hashtags_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - -# Test playground -test_playground_SOURCES = test-playground.cc -test_playground_LDFLAGS = -L../.. -test_playground_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) -CLEANFILES = \ - underpass.log \ - pq-test.log \ - change-test.log \ - geo-test.log \ - stats-test.log \ - val-test.log \ - statsconfig-test.log \ - planetreplicator-test.log \ - areafilter-test.log \ - hashtags-test.log \ - replication-test.log - -RUNTESTFLAGS = -xml -all: all-am - -.SUFFIXES: -.SUFFIXES: .cc .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/testsuite/libunderpass.all/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/testsuite/libunderpass.all/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -areafilter-test$(EXEEXT): $(areafilter_test_OBJECTS) $(areafilter_test_DEPENDENCIES) $(EXTRA_areafilter_test_DEPENDENCIES) - @rm -f areafilter-test$(EXEEXT) - $(AM_V_CXXLD)$(areafilter_test_LINK) $(areafilter_test_OBJECTS) $(areafilter_test_LDADD) $(LIBS) - -change-test$(EXEEXT): $(change_test_OBJECTS) $(change_test_DEPENDENCIES) $(EXTRA_change_test_DEPENDENCIES) - @rm -f change-test$(EXEEXT) - $(AM_V_CXXLD)$(change_test_LINK) $(change_test_OBJECTS) $(change_test_LDADD) $(LIBS) - -geo-test$(EXEEXT): $(geo_test_OBJECTS) $(geo_test_DEPENDENCIES) $(EXTRA_geo_test_DEPENDENCIES) - @rm -f geo-test$(EXEEXT) - $(AM_V_CXXLD)$(geo_test_LINK) $(geo_test_OBJECTS) $(geo_test_LDADD) $(LIBS) - -hashtags-test$(EXEEXT): $(hashtags_test_OBJECTS) $(hashtags_test_DEPENDENCIES) $(EXTRA_hashtags_test_DEPENDENCIES) - @rm -f hashtags-test$(EXEEXT) - $(AM_V_CXXLD)$(hashtags_test_LINK) $(hashtags_test_OBJECTS) $(hashtags_test_LDADD) $(LIBS) - -planetreplicator-test$(EXEEXT): $(planetreplicator_test_OBJECTS) $(planetreplicator_test_DEPENDENCIES) $(EXTRA_planetreplicator_test_DEPENDENCIES) - @rm -f planetreplicator-test$(EXEEXT) - $(AM_V_CXXLD)$(planetreplicator_test_LINK) $(planetreplicator_test_OBJECTS) $(planetreplicator_test_LDADD) $(LIBS) - -pq-test$(EXEEXT): $(pq_test_OBJECTS) $(pq_test_DEPENDENCIES) $(EXTRA_pq_test_DEPENDENCIES) - @rm -f pq-test$(EXEEXT) - $(AM_V_CXXLD)$(pq_test_LINK) $(pq_test_OBJECTS) $(pq_test_LDADD) $(LIBS) - -stats-test$(EXEEXT): $(stats_test_OBJECTS) $(stats_test_DEPENDENCIES) $(EXTRA_stats_test_DEPENDENCIES) - @rm -f stats-test$(EXEEXT) - $(AM_V_CXXLD)$(stats_test_LINK) $(stats_test_OBJECTS) $(stats_test_LDADD) $(LIBS) - -statsconfig-test$(EXEEXT): $(statsconfig_test_OBJECTS) $(statsconfig_test_DEPENDENCIES) $(EXTRA_statsconfig_test_DEPENDENCIES) - @rm -f statsconfig-test$(EXEEXT) - $(AM_V_CXXLD)$(statsconfig_test_LINK) $(statsconfig_test_OBJECTS) $(statsconfig_test_LDADD) $(LIBS) - -test-playground$(EXEEXT): $(test_playground_OBJECTS) $(test_playground_DEPENDENCIES) $(EXTRA_test_playground_DEPENDENCIES) - @rm -f test-playground$(EXEEXT) - $(AM_V_CXXLD)$(test_playground_LINK) $(test_playground_OBJECTS) $(test_playground_LDADD) $(LIBS) - -val-test$(EXEEXT): $(val_test_OBJECTS) $(val_test_DEPENDENCIES) $(EXTRA_val_test_DEPENDENCIES) - @rm -f val-test$(EXEEXT) - $(AM_V_CXXLD)$(val_test_LINK) $(val_test_OBJECTS) $(val_test_LDADD) $(LIBS) - -yaml-test$(EXEEXT): $(yaml_test_OBJECTS) $(yaml_test_DEPENDENCIES) $(EXTRA_yaml_test_DEPENDENCIES) - @rm -f yaml-test$(EXEEXT) - $(AM_V_CXXLD)$(yaml_test_LINK) $(yaml_test_OBJECTS) $(yaml_test_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -include ./$(DEPDIR)/areafilter-test.Po # am--include-marker -include ./$(DEPDIR)/change_test-change-test.Po # am--include-marker -include ./$(DEPDIR)/geo_test-geo-test.Po # am--include-marker -include ./$(DEPDIR)/hashtags-test.Po # am--include-marker -include ./$(DEPDIR)/planetreplicator-test.Po # am--include-marker -include ./$(DEPDIR)/pq_test-pq-test.Po # am--include-marker -include ./$(DEPDIR)/stats_test-stats-test.Po # am--include-marker -include ./$(DEPDIR)/statsconfig-test.Po # am--include-marker -include ./$(DEPDIR)/test-playground.Po # am--include-marker -include ./$(DEPDIR)/val_test-val-test.Po # am--include-marker -include ./$(DEPDIR)/yaml_test-yaml-test.Po # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.cc.o: - $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< - $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -# $(AM_V_CXX)source='$<' object='$@' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ $< - -.cc.obj: - $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` - $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -# $(AM_V_CXX)source='$<' object='$@' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cc.lo: - $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< - $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -# $(AM_V_CXX)source='$<' object='$@' libtool=yes \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(LTCXXCOMPILE) -c -o $@ $< - -change_test-change-test.o: change-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(change_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT change_test-change-test.o -MD -MP -MF $(DEPDIR)/change_test-change-test.Tpo -c -o change_test-change-test.o `test -f 'change-test.cc' || echo '$(srcdir)/'`change-test.cc - $(AM_V_at)$(am__mv) $(DEPDIR)/change_test-change-test.Tpo $(DEPDIR)/change_test-change-test.Po -# $(AM_V_CXX)source='change-test.cc' object='change_test-change-test.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(change_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o change_test-change-test.o `test -f 'change-test.cc' || echo '$(srcdir)/'`change-test.cc - -change_test-change-test.obj: change-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(change_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT change_test-change-test.obj -MD -MP -MF $(DEPDIR)/change_test-change-test.Tpo -c -o change_test-change-test.obj `if test -f 'change-test.cc'; then $(CYGPATH_W) 'change-test.cc'; else $(CYGPATH_W) '$(srcdir)/change-test.cc'; fi` - $(AM_V_at)$(am__mv) $(DEPDIR)/change_test-change-test.Tpo $(DEPDIR)/change_test-change-test.Po -# $(AM_V_CXX)source='change-test.cc' object='change_test-change-test.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(change_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o change_test-change-test.obj `if test -f 'change-test.cc'; then $(CYGPATH_W) 'change-test.cc'; else $(CYGPATH_W) '$(srcdir)/change-test.cc'; fi` - -geo_test-geo-test.o: geo-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(geo_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT geo_test-geo-test.o -MD -MP -MF $(DEPDIR)/geo_test-geo-test.Tpo -c -o geo_test-geo-test.o `test -f 'geo-test.cc' || echo '$(srcdir)/'`geo-test.cc - $(AM_V_at)$(am__mv) $(DEPDIR)/geo_test-geo-test.Tpo $(DEPDIR)/geo_test-geo-test.Po -# $(AM_V_CXX)source='geo-test.cc' object='geo_test-geo-test.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(geo_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o geo_test-geo-test.o `test -f 'geo-test.cc' || echo '$(srcdir)/'`geo-test.cc - -geo_test-geo-test.obj: geo-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(geo_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT geo_test-geo-test.obj -MD -MP -MF $(DEPDIR)/geo_test-geo-test.Tpo -c -o geo_test-geo-test.obj `if test -f 'geo-test.cc'; then $(CYGPATH_W) 'geo-test.cc'; else $(CYGPATH_W) '$(srcdir)/geo-test.cc'; fi` - $(AM_V_at)$(am__mv) $(DEPDIR)/geo_test-geo-test.Tpo $(DEPDIR)/geo_test-geo-test.Po -# $(AM_V_CXX)source='geo-test.cc' object='geo_test-geo-test.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(geo_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o geo_test-geo-test.obj `if test -f 'geo-test.cc'; then $(CYGPATH_W) 'geo-test.cc'; else $(CYGPATH_W) '$(srcdir)/geo-test.cc'; fi` - -pq_test-pq-test.o: pq-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pq_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pq_test-pq-test.o -MD -MP -MF $(DEPDIR)/pq_test-pq-test.Tpo -c -o pq_test-pq-test.o `test -f 'pq-test.cc' || echo '$(srcdir)/'`pq-test.cc - $(AM_V_at)$(am__mv) $(DEPDIR)/pq_test-pq-test.Tpo $(DEPDIR)/pq_test-pq-test.Po -# $(AM_V_CXX)source='pq-test.cc' object='pq_test-pq-test.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pq_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pq_test-pq-test.o `test -f 'pq-test.cc' || echo '$(srcdir)/'`pq-test.cc - -pq_test-pq-test.obj: pq-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pq_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pq_test-pq-test.obj -MD -MP -MF $(DEPDIR)/pq_test-pq-test.Tpo -c -o pq_test-pq-test.obj `if test -f 'pq-test.cc'; then $(CYGPATH_W) 'pq-test.cc'; else $(CYGPATH_W) '$(srcdir)/pq-test.cc'; fi` - $(AM_V_at)$(am__mv) $(DEPDIR)/pq_test-pq-test.Tpo $(DEPDIR)/pq_test-pq-test.Po -# $(AM_V_CXX)source='pq-test.cc' object='pq_test-pq-test.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pq_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pq_test-pq-test.obj `if test -f 'pq-test.cc'; then $(CYGPATH_W) 'pq-test.cc'; else $(CYGPATH_W) '$(srcdir)/pq-test.cc'; fi` - -stats_test-stats-test.o: stats-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stats_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stats_test-stats-test.o -MD -MP -MF $(DEPDIR)/stats_test-stats-test.Tpo -c -o stats_test-stats-test.o `test -f 'stats-test.cc' || echo '$(srcdir)/'`stats-test.cc - $(AM_V_at)$(am__mv) $(DEPDIR)/stats_test-stats-test.Tpo $(DEPDIR)/stats_test-stats-test.Po -# $(AM_V_CXX)source='stats-test.cc' object='stats_test-stats-test.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stats_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stats_test-stats-test.o `test -f 'stats-test.cc' || echo '$(srcdir)/'`stats-test.cc - -stats_test-stats-test.obj: stats-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stats_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stats_test-stats-test.obj -MD -MP -MF $(DEPDIR)/stats_test-stats-test.Tpo -c -o stats_test-stats-test.obj `if test -f 'stats-test.cc'; then $(CYGPATH_W) 'stats-test.cc'; else $(CYGPATH_W) '$(srcdir)/stats-test.cc'; fi` - $(AM_V_at)$(am__mv) $(DEPDIR)/stats_test-stats-test.Tpo $(DEPDIR)/stats_test-stats-test.Po -# $(AM_V_CXX)source='stats-test.cc' object='stats_test-stats-test.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stats_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stats_test-stats-test.obj `if test -f 'stats-test.cc'; then $(CYGPATH_W) 'stats-test.cc'; else $(CYGPATH_W) '$(srcdir)/stats-test.cc'; fi` - -val_test-val-test.o: val-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(val_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT val_test-val-test.o -MD -MP -MF $(DEPDIR)/val_test-val-test.Tpo -c -o val_test-val-test.o `test -f 'val-test.cc' || echo '$(srcdir)/'`val-test.cc - $(AM_V_at)$(am__mv) $(DEPDIR)/val_test-val-test.Tpo $(DEPDIR)/val_test-val-test.Po -# $(AM_V_CXX)source='val-test.cc' object='val_test-val-test.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(val_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o val_test-val-test.o `test -f 'val-test.cc' || echo '$(srcdir)/'`val-test.cc - -val_test-val-test.obj: val-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(val_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT val_test-val-test.obj -MD -MP -MF $(DEPDIR)/val_test-val-test.Tpo -c -o val_test-val-test.obj `if test -f 'val-test.cc'; then $(CYGPATH_W) 'val-test.cc'; else $(CYGPATH_W) '$(srcdir)/val-test.cc'; fi` - $(AM_V_at)$(am__mv) $(DEPDIR)/val_test-val-test.Tpo $(DEPDIR)/val_test-val-test.Po -# $(AM_V_CXX)source='val-test.cc' object='val_test-val-test.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(val_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o val_test-val-test.obj `if test -f 'val-test.cc'; then $(CYGPATH_W) 'val-test.cc'; else $(CYGPATH_W) '$(srcdir)/val-test.cc'; fi` - -yaml_test-yaml-test.o: yaml-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT yaml_test-yaml-test.o -MD -MP -MF $(DEPDIR)/yaml_test-yaml-test.Tpo -c -o yaml_test-yaml-test.o `test -f 'yaml-test.cc' || echo '$(srcdir)/'`yaml-test.cc - $(AM_V_at)$(am__mv) $(DEPDIR)/yaml_test-yaml-test.Tpo $(DEPDIR)/yaml_test-yaml-test.Po -# $(AM_V_CXX)source='yaml-test.cc' object='yaml_test-yaml-test.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o yaml_test-yaml-test.o `test -f 'yaml-test.cc' || echo '$(srcdir)/'`yaml-test.cc - -yaml_test-yaml-test.obj: yaml-test.cc - $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT yaml_test-yaml-test.obj -MD -MP -MF $(DEPDIR)/yaml_test-yaml-test.Tpo -c -o yaml_test-yaml-test.obj `if test -f 'yaml-test.cc'; then $(CYGPATH_W) 'yaml-test.cc'; else $(CYGPATH_W) '$(srcdir)/yaml-test.cc'; fi` - $(AM_V_at)$(am__mv) $(DEPDIR)/yaml_test-yaml-test.Tpo $(DEPDIR)/yaml_test-yaml-test.Po -# $(AM_V_CXX)source='yaml-test.cc' object='yaml_test-yaml-test.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ -# $(AM_V_CXX_no)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(yaml_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o yaml_test-yaml-test.obj `if test -f 'yaml-test.cc'; then $(CYGPATH_W) 'yaml-test.cc'; else $(CYGPATH_W) '$(srcdir)/yaml-test.cc'; fi` - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -check-DEJAGNU: site.exp - srcdir='$(srcdir)'; export srcdir; \ - EXPECT=$(EXPECT); export EXPECT; \ - if $(SHELL) -c "$(RUNTEST) --version" > /dev/null 2>&1; then \ - exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \ - if $(RUNTEST) $(RUNTESTDEFAULTFLAGS) $(AM_RUNTESTFLAGS) $(RUNTESTFLAGS); \ - then :; else exit_status=1; fi; \ - done; \ - else echo "WARNING: could not find '$(RUNTEST)'" 1>&2; :;\ - fi; \ - exit $$exit_status -site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG) - @echo 'Making a new site.exp file ...' - @echo '## these variables are automatically generated by make ##' >site.tmp - @echo '# Do not edit here. If you wish to override these values' >>site.tmp - @echo '# edit the last section' >>site.tmp - @echo 'set srcdir "$(srcdir)"' >>site.tmp - @echo "set objdir `pwd`" >>site.tmp - @echo 'set build_alias "$(build_alias)"' >>site.tmp - @echo 'set build_triplet $(build_triplet)' >>site.tmp - @echo 'set host_alias "$(host_alias)"' >>site.tmp - @echo 'set host_triplet $(host_triplet)' >>site.tmp - @list='$(EXTRA_DEJAGNU_SITE_CONFIG)'; for f in $$list; do \ - echo "## Begin content included from file $$f. Do not modify. ##" \ - && cat `test -f "$$f" || echo '$(srcdir)/'`$$f \ - && echo "## End content included from file $$f. ##" \ - || exit 1; \ - done >> site.tmp - @echo "## End of auto-generated content; you can edit from here. ##" >> site.tmp - @if test -f site.exp; then \ - sed -e '1,/^## End of auto-generated content.*##/d' site.exp >> site.tmp; \ - fi - @-rm -f site.bak - @test ! -f site.exp || mv site.exp site.bak - @mv site.tmp site.exp - -distclean-DEJAGNU: - -rm -f site.exp site.bak - -l='$(DEJATOOL)'; for tool in $$l; do \ - rm -f $$tool.sum $$tool.log; \ - done - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/areafilter-test.Po - -rm -f ./$(DEPDIR)/change_test-change-test.Po - -rm -f ./$(DEPDIR)/geo_test-geo-test.Po - -rm -f ./$(DEPDIR)/hashtags-test.Po - -rm -f ./$(DEPDIR)/planetreplicator-test.Po - -rm -f ./$(DEPDIR)/pq_test-pq-test.Po - -rm -f ./$(DEPDIR)/stats_test-stats-test.Po - -rm -f ./$(DEPDIR)/statsconfig-test.Po - -rm -f ./$(DEPDIR)/test-playground.Po - -rm -f ./$(DEPDIR)/val_test-val-test.Po - -rm -f ./$(DEPDIR)/yaml_test-yaml-test.Po - -rm -f Makefile -distclean-am: clean-am distclean-DEJAGNU distclean-compile \ - distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/areafilter-test.Po - -rm -f ./$(DEPDIR)/change_test-change-test.Po - -rm -f ./$(DEPDIR)/geo_test-geo-test.Po - -rm -f ./$(DEPDIR)/hashtags-test.Po - -rm -f ./$(DEPDIR)/planetreplicator-test.Po - -rm -f ./$(DEPDIR)/pq_test-pq-test.Po - -rm -f ./$(DEPDIR)/stats_test-stats-test.Po - -rm -f ./$(DEPDIR)/statsconfig-test.Po - -rm -f ./$(DEPDIR)/test-playground.Po - -rm -f ./$(DEPDIR)/val_test-val-test.Po - -rm -f ./$(DEPDIR)/yaml_test-yaml-test.Po - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: check-am install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-DEJAGNU \ - check-am clean clean-checkPROGRAMS clean-generic clean-libtool \ - cscopelist-am ctags ctags-am distclean distclean-DEJAGNU \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/testsuite/libunderpass.all/Makefile.am b/src/testsuite/libunderpass.all/Makefile.am index 5073142e..f52ee79e 100644 --- a/src/testsuite/libunderpass.all/Makefile.am +++ b/src/testsuite/libunderpass.all/Makefile.am @@ -75,12 +75,12 @@ geo_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) val_test_SOURCES = val-test.cc val_test_LDFLAGS = -L../.. val_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -val_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) ../../validate/hotosm.lo +val_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) ../../validate/defaultvalidation.lo ../../validate/geospatial.lo ../../validate/semantic.lo val_unsquared_test_SOURCES = val-unsquared-test.cc val_unsquared_test_LDFLAGS = -L../.. val_unsquared_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) -val_unsquared_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) ../../validate/hotosm.lo +val_unsquared_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) ../../validate/defaultvalidation.lo ../../validate/geospatial.lo ../../validate/semantic.lo # Test the replication classes #replication_test_SOURCES = replication-test.cc @@ -88,11 +88,6 @@ val_unsquared_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) ../../validate/hotos #rplication_test_CPPFLAGS = -DDATADIR=\"$(TOPSRC)\" -I$(TOPSRC) #replication_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) -# Test the OSM DB classes -#hotosm_test_SOURCES = hotosm-test.cc -#hotosm_test_LDFLAGS = -L../.. -#hotosm_test_LDADD = -lpqxx -lunderpass $(BOOST_LIBS) - # Test the OSM Stats class stats_test_SOURCES = stats-test.cc stats_test_LDFLAGS = -L../.. diff --git a/src/testsuite/libunderpass.all/hotosm-test.cc b/src/testsuite/libunderpass.all/hotosm-test.cc deleted file mode 100644 index 4cd900de..00000000 --- a/src/testsuite/libunderpass.all/hotosm-test.cc +++ /dev/null @@ -1,157 +0,0 @@ -// -// Copyright (c) 2020, 2021, 2022, 2023 Humanitarian OpenStreetMap Team -// -// This file is part of Underpass. -// -// Underpass is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Underpass is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Underpass. If not, see . -// - -#include -#include -#include -#include "hotosm.hh" - -#include -#include "boost/date_time/posix_time/posix_time.hpp" -#include "boost/date_time/gregorian/gregorian.hpp" - -using namespace apidb; -using namespace boost::posix_time; -using namespace boost::gregorian; - -namespace hotosmtest { - -TestState runtest; - -class TestPG : public QueryStats -{ -public: - TestPG() { - uid = 760688; - }; -private: - long uid; -}; - -class TestTM : public QueryTM -{ -public: - TestTM() { - uid = 760688; - }; -private: - long uid; -}; - -void test_pgsnapshot(void); -void test_tm(void); -void test_leaderboard(void); - -int -main(int argc, char *argv[]) -{ - - test_pgsnapshot(); - test_tm(); - test_leaderboard(); -} - -void -test_pgsnapshot(void) -{ -// FIXME: database should be a command line argument - std::string database = "pgsnapshot"; - long uid = 7606880; - TestPG testpg; - - // These testpgs are for the base class, which handles - // the database connection. - if (testpg.connect(database)) { - runtest.pass("QueryDB::connect()"); - } else { - runtest.fail("QueryDB::connect()"); - } - std::string sql = "SELECT * FROM ways;"; - pqxx::result result = testpg.query(sql); - if (!result.empty()) { - runtest.pass("QueryDB::query()"); - } else { - runtest.fail("QueryDB::query()"); - } - - ptime start = time_from_string("2010-07-08 13:29:46"); - ptime end = second_clock::local_time(); - - // std::cout << to_simple_string(start) << std::endl; - // std::cout << to_simple_string(end) << std::endl; - - long ret = testpg.getCount(QueryStats::building, uid, - QueryStats::totals, start, end); - if (ret >= 0) { - runtest.pass("getCount(QueryStats::building)"); - } else { - runtest.fail("getCount(QueryStats::building)"); - } - ret = testpg.getCount(QueryStats::highway, uid, - QueryStats::totals, start, end); - if (ret >= 0) { - runtest.pass("getCount(QueryStats::highway)"); - } else { - runtest.fail("getCount(QueryStats::highway)"); - } - - ret = testpg.getCount(QueryStats::waterway, uid, - QueryStats::totals, start, end); - if (ret >= 0) { - runtest.pass("getCount(QueryStats::waterway)"); - } else { - runtest.fail("getCount(QueryStats::waterway)"); - } - - ret = testpg.getCount(QueryStats::highway, uid, - QueryStats::changesets, start, end); - if (ret >= 0) { - runtest.pass("getCount(QueryStats::highway,changesets)"); - } else { - runtest.fail("getCount(QueryStats::highway,changesets)"); - } - ret = testpg.getCount(QueryStats::building, uid, - QueryStats::changesets, start, end); - if (ret >= 0) { - runtest.pass("getCount(QueryStats::building,changesets)"); - } else { - runtest.fail("getCount(QueryStats::building,changesets)"); - } - ret = testpg.getCount(QueryStats::waterway, uid, - QueryStats::changesets, start, end); - if (ret >= 0) { - runtest.pass("getCount(QueryStats::waterway,changesets)"); - } else { - runtest.fail("getCount(QueryStats::waterway,changesets)"); - } - - ret = testpg.getLength(QueryStats::waterway, uid, start, end); - if (ret >= 0) { - runtest.pass("getCount(QueryStats::getLength(waterway))"); - } else { - runtest.fail("getCount(QueryStats::getLength(waterway)"); - } -} - -} - -// local Variables: -// mode: C++ -// indent-tabs-mode: nil -// End: diff --git a/src/testsuite/libunderpass.all/pq-test.cc b/src/testsuite/libunderpass.all/pq-test.cc index e6d14d2e..4f4ed3dc 100644 --- a/src/testsuite/libunderpass.all/pq-test.cc +++ b/src/testsuite/libunderpass.all/pq-test.cc @@ -58,7 +58,7 @@ main(int argc, char *argv[]) } ret = tp.parseURL("localhost/testdb"); //tp.dump(); - if (ret && tp.dbname == "dbname=testdb" && tp.host.empty()) { + if (ret && tp.dbname == "dbname=testdb" && tp.host == "host=localhost") { runtest.pass("PQ::parseURL(localhost/dbname)"); } else { runtest.fail("PQ::parseURL(localhost/dbname)"); diff --git a/src/testsuite/libunderpass.all/val-test.cc b/src/testsuite/libunderpass.all/val-test.cc index 8022e65d..0b0dfc9b 100644 --- a/src/testsuite/libunderpass.all/val-test.cc +++ b/src/testsuite/libunderpass.all/val-test.cc @@ -31,7 +31,7 @@ #include #include -#include "validate/hotosm.hh" +#include "validate/defaultvalidation.hh" #include "validate/validate.hh" #include "stats/querystats.hh" #include "osm/osmobjects.hh" @@ -48,9 +48,8 @@ class TestOsmChange : public osmchange::OsmChangeFile {}; typedef std::shared_ptr(plugin_t)(); -int test_semantic_building(std::shared_ptr &plugin); -// void test_semantic_highway(std::shared_ptr &plugin); -int test_geometry_building(std::shared_ptr &plugin); +int test_semantic(std::shared_ptr &plugin); +int test_geospatial(std::shared_ptr &plugin); int main(int argc, char *argv[]) @@ -68,7 +67,7 @@ main(int argc, char *argv[]) lib_path / "libunderpass.so", "create_plugin", boost::dll::load_mode::append_decorations ); - log_debug("Loaded plugin hotosm!"); + log_debug("Loaded plugin!"); } catch (std::exception& e) { log_debug("Couldn't load plugin! %1%", e.what()); exit(0); @@ -78,9 +77,8 @@ main(int argc, char *argv[]) auto plugin = creator(); plugin->loadConfig(testValidationConfig); - test_semantic_building(plugin); - // test_semantic_highway(plugin); - test_geometry_building(plugin); + test_semantic(plugin); + test_geospatial(plugin); } osmobjects::OsmWay readOsmWayFromFile(std::string filename) { @@ -96,79 +94,67 @@ osmobjects::OsmWay readOsmWayFromFile(std::string filename) { return *osmchange.changes.front().get()->ways.front().get(); } -void -test_semantic_highway(std::shared_ptr &plugin) { - // Way - checkWay() +int +test_semantic(std::shared_ptr &plugin) { - auto way = readOsmWayFromFile("/testsuite/testdata/validation/highway.osc"); + // Node - checkNode() - way.addTag("highway", "primary"); + osmobjects::OsmNode node; + node.id = 11111; + node.changeset = 22222; - // Has an invalid key=value - way.addTag("surface", "sponge"); - auto status = plugin->checkWay(way, "highway"); - if (status->hasStatus(badvalue)) { - runtest.pass("Validate::checkWay(bad value) [semantic highway]"); + // Node with no tags + auto status = plugin->checkNode(node, "building"); + if (status->osm_id == 11111 && status->hasStatus(notags)) { + runtest.pass("Validate::checkNode(no tags) [semantic building]"); } else { - runtest.fail("Validate::checkWay(bad value) [semantic highway]"); + runtest.fail("Validate::checkNode(no tags) [semantic building]"); + return 1; } - way.addTag("surface", "unpaved"); - way.addTag("smoothness", "very_horrible"); - way.addTag("highway", "unclassified"); - - // Has all valid tags - status = plugin->checkWay(way, "highway"); - if (!status->hasStatus(badvalue)) { - runtest.pass("Validate::checkWay(no bad values) [semantic highway]"); + // Node with tag with no value + node.addTag("building", ""); + status = plugin->checkNode(node, "building"); + if (status->hasStatus(badvalue)) { + runtest.pass("Validate::checkNode(no value) [semantic building]"); } else { - runtest.fail("Validate::checkWay(no bad values) [semantic highway]"); + runtest.fail("Validate::checkNode(no value) [semantic building]"); + return 1; } -} -int -test_semantic_building(std::shared_ptr &plugin) { - // checkTag() - - // Existence of key=value - auto status = plugin->checkTag("building", "yes"); - if (!status->hasStatus(badvalue)) { - runtest.pass("Validate::checkTag(good tag) [semantic building]"); + node.addTag("building", "\"yes\""); + status = plugin->checkNode(node, "building"); + if (status->hasStatus(badvalue)) { + runtest.pass("Validate::checkNode(double quotes) [semantic building]"); } else { - runtest.fail("Validate::checkTag(good tag) [semantic building]"); + runtest.fail("Validate::checkNode(double quotes) [semantic building]"); return 1; } - // Empty value - status = plugin->checkTag("building", ""); + node.addTag("building", "'yes'"); + status = plugin->checkNode(node, "building"); if (status->hasStatus(badvalue)) { - runtest.pass("Validate::checkTag(empty value) [semantic building]"); + runtest.pass("Validate::checkNode(single quotes) [semantic building]"); } else { - runtest.fail("Validate::checkTag(empty value) [semantic building]"); + runtest.fail("Validate::checkNode(single quotes) [semantic building]"); return 1; } - // Invalid tag, not listed into the config file (ex: foo bar=bar) - status = plugin->checkTag("foo bar", "bar"); + node.addTag("building", "yes "); + status = plugin->checkNode(node, "building"); if (status->hasStatus(badvalue)) { - runtest.pass("Validate::checkTag(space in key) [semantic building]"); + runtest.pass("Validate::checkNode(single quotes) [semantic building]"); } else { - runtest.fail("Validate::checkTag(space in key) [semantic building]"); + runtest.fail("Validate::checkNode(single quotes) [semantic building]"); return 1; } - // Node - checkPOI() - - osmobjects::OsmNode node; - node.id = 11111; - node.changeset = 22222; - - // Node with no tags - status = plugin->checkPOI(node, "building"); - if (status->osm_id == 11111 && status->hasStatus(notags)) { - runtest.pass("Validate::checkPOI(no tags) [semantic building]"); + node.addTag("building", "yes"); + status = plugin->checkNode(node, "building"); + if (!status->hasStatus(badvalue)) { + runtest.pass("Validate::checkNode(good value) [semantic building]"); } else { - runtest.fail("Validate::checkPOI(no tags) [semantic building]"); + runtest.fail("Validate::checkNode(good value) [semantic building]"); return 1; } @@ -178,20 +164,20 @@ test_semantic_building(std::shared_ptr &plugin) { // Has valid tags, but it's incomplete node_place.addTag("place", "city"); - status = plugin->checkPOI(node_place, "place"); + status = plugin->checkNode(node_place, "place"); if (!status->hasStatus(badvalue) && status->hasStatus(incomplete)) { - runtest.pass("Validate::checkPOI(incomplete but correct tagging) [semantic place]"); + runtest.pass("Validate::checkNode(incomplete but correct tagging) [semantic place]"); } else { - runtest.fail("Validate::checkPOI(incomplete but correct tagging) [semantic place]"); + runtest.fail("Validate::checkNode(incomplete but correct tagging) [semantic place]"); return 1; } node_place.addTag("name", "Electric City"); - status = plugin->checkPOI(node_place, "place"); + status = plugin->checkNode(node_place, "place"); if (!status->hasStatus(badvalue) && !status->hasStatus(incomplete)) { - runtest.pass("Validate::checkPOI(complete and correct tagging) [semantic place]"); + runtest.pass("Validate::checkNode(complete and correct tagging) [semantic place]"); } else { - runtest.fail("Validate::checkPOI(complete and correct tagging) [semantic place]"); + runtest.fail("Validate::checkNode(complete and correct tagging) [semantic place]"); return 1; } @@ -199,20 +185,20 @@ test_semantic_building(std::shared_ptr &plugin) { // Has an invalid key=value ... node.addTag("building:material", "sponge"); - status = plugin->checkPOI(node, "building"); + status = plugin->checkNode(node, "building"); if (status->hasStatus(badvalue)) { - runtest.pass("Validate::checkPOI(bad value) [semantic building]"); + runtest.pass("Validate::checkNode(bad value) [semantic building]"); } else { - runtest.fail("Validate::checkPOI(bad value) [semantic building]"); + runtest.fail("Validate::checkNode(bad value) [semantic building]"); return 1; } // But it's complete - status = plugin->checkPOI(node, "building"); + status = plugin->checkNode(node, "building"); if (status->hasStatus(complete)) { - runtest.pass("Validate::checkPOI(complete) [semantic building]"); + runtest.pass("Validate::checkNode(complete) [semantic building]"); } else { - runtest.fail("Validate::checkPOI(complete) [semantic building]"); + runtest.fail("Validate::checkNode(complete) [semantic building]"); return 1; } @@ -221,11 +207,11 @@ test_semantic_building(std::shared_ptr &plugin) { node.addTag("roof:material", "roof_tiles"); // Has all valid tags - status = plugin->checkPOI(node, "building"); + status = plugin->checkNode(node, "building"); if (!status->hasStatus(badvalue)) { - runtest.pass("Validate::checkPOI(no bad values) [semantic building]"); + runtest.pass("Validate::checkNode(no bad values) [semantic building]"); } else { - runtest.fail("Validate::checkPOI(no bad values) [semantic building]"); + runtest.fail("Validate::checkNode(no bad values) [semantic building]"); return 1; } @@ -287,17 +273,13 @@ test_semantic_building(std::shared_ptr &plugin) { return 1; } - + return 0; - // TODO: Has empty value - // TODO: Has single quote - // TODO: Has double quotes - // TODO: Has spaces } // Geometry tests for buildings int -test_geometry_building(std::shared_ptr &plugin) +test_geospatial(std::shared_ptr &plugin) { // Bad geometry @@ -307,11 +289,13 @@ test_geometry_building(std::shared_ptr &plugin) filespec += "/testsuite/testdata/validation/rect.osc"; if (boost::filesystem::exists(filespec)) { ocf.readChanges(filespec); + ocf.buildGeometriesFromNodeCache(); } for (auto it = std::begin(ocf.changes); it != std::end(ocf.changes); ++it) { osmchange::OsmChange *change = it->get(); for (auto wit = std::begin(change->ways); wit != std::end(change->ways); ++wit) { osmobjects::OsmWay *way = wit->get(); + auto status = plugin->checkWay(*way, "building"); // status->dump(); // std::cerr << way->tags["note"] << std::endl; @@ -409,29 +393,29 @@ test_geometry_building(std::shared_ptr &plugin) allways2.push_back(std::make_shared(way3)); // Overlapping (function) - if (plugin->overlaps(allways, way)) { - runtest.pass("Validate::overlaps() [geometry building]"); - } else { - runtest.fail("Validate::overlaps() [geometry building]"); - } - if (plugin->overlaps(allways, way3)) { - runtest.pass("Validate::overlaps(no) [geometry building]"); - } else { - runtest.fail("Validate::overlaps(no) [geometry building]"); - } + // if (plugin->overlaps(allways, way)) { + // runtest.pass("Validate::overlaps() [geometry building]"); + // } else { + // runtest.fail("Validate::overlaps() [geometry building]"); + // } + // if (plugin->overlaps(allways, way3)) { + // runtest.pass("Validate::overlaps(no) [geometry building]"); + // } else { + // runtest.fail("Validate::overlaps(no) [geometry building]"); + // } // Duplicate (function) - allways.push_back(std::make_shared(way)); - if (plugin->duplicate(allways, way2)) { - runtest.pass("Validate::duplicate() [geometry building]"); - } else { - runtest.fail("Validate::duplicate() [geometry building]"); - } - if (!plugin->duplicate(allways2, way2)) { - runtest.pass("Validate::duplicate(no) [geometry building]"); - } else { - runtest.fail("Validate::duplicate(no) [geometry building]"); - } + // allways.push_back(std::make_shared(way)); + // if (plugin->duplicate(allways, way2)) { + // runtest.pass("Validate::duplicate() [geometry building]"); + // } else { + // runtest.fail("Validate::duplicate() [geometry building]"); + // } + // if (!plugin->duplicate(allways2, way2)) { + // runtest.pass("Validate::duplicate(no) [geometry building]"); + // } else { + // runtest.fail("Validate::duplicate(no) [geometry building]"); + // } // Overlapping, duplicate osmchange::OsmChangeFile osmfoverlaping; diff --git a/src/testsuite/libunderpass.all/val-unsquared-test.cc b/src/testsuite/libunderpass.all/val-unsquared-test.cc index 0c2d8196..4b857eb5 100644 --- a/src/testsuite/libunderpass.all/val-unsquared-test.cc +++ b/src/testsuite/libunderpass.all/val-unsquared-test.cc @@ -20,7 +20,7 @@ #include #include #include "validate/validate.hh" -#include "validate/hotosm.hh" +#include "validate/defaultvalidation.hh" #include "osm/osmobjects.hh" #include "osm/osmchange.hh" #include "utils/log.hh" @@ -41,6 +41,7 @@ osmobjects::OsmWay readOsmWayFromFile(std::string filename) { } else { log_debug("Couldn't load ! %1%", filespec); }; + osmchange.buildGeometriesFromNodeCache(); return *osmchange.changes.front().get()->ways.front().get(); } @@ -52,7 +53,7 @@ main(int argc, char *argv[]) dbglogfile.setLogFilename("val-unsquared-test.log"); dbglogfile.setVerbosity(3); - auto plugin = std::make_shared(); + auto plugin = std::make_shared(); // Squared building 1 auto way = readOsmWayFromFile("/testsuite/testdata/validation/squared-building-1.osm"); diff --git a/src/testsuite/testdata/stats/test_stats.yaml b/src/testsuite/testdata/stats/test_stats.yaml index 6623d303..b150dc05 100644 --- a/src/testsuite/testdata/stats/test_stats.yaml +++ b/src/testsuite/testdata/stats/test_stats.yaml @@ -7,7 +7,7 @@ - modified_building: - 1 - added_building: - - 2 + - 1 - modified_waterway: - 1 - added_waterway: diff --git a/src/testsuite/testdata/validation/rect.osc b/src/testsuite/testdata/validation/rect.osc index 71a8e3ad..b5e1a13c 100644 --- a/src/testsuite/testdata/validation/rect.osc +++ b/src/testsuite/testdata/validation/rect.osc @@ -1,6 +1,22 @@ - + + + + + + + + + + + + + + + + + @@ -16,4 +32,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/yaml.cc b/src/utils/yaml.cc index 615bed6a..c6c3e20e 100644 --- a/src/utils/yaml.cc +++ b/src/utils/yaml.cc @@ -95,7 +95,8 @@ std::pair Yaml::process_line(std::string line ) { } std::string Yaml::scan_ident(std::string line) { - const char *c = line.substr(0, 1).c_str(); + std::string firstChar = line.substr(0, 1); + const char *c = firstChar.c_str(); if (ident_char == '\0') { if (*c == idents[0]) { this->ident_char = idents[0]; diff --git a/src/validate/Makefile.am b/src/validate/Makefile.am index 3343d7cc..6e4631d7 100644 --- a/src/validate/Makefile.am +++ b/src/validate/Makefile.am @@ -32,7 +32,9 @@ BOOST_LIBS = $(BOOST_DATE_TIME_LIB) \ $(BOOST_LOCALE_LIB) libunderpass_la_SOURCES = \ - hotosm.cc hotosm.hh \ + geospatial.cc geospatial.hh \ + semantic.cc semantic.hh \ + defaultvalidation.cc defaultvalidation.hh \ validate.hh libunderpass_la_LDFLAGS = -module -avoid-version diff --git a/src/validate/defaultvalidation.cc b/src/validate/defaultvalidation.cc new file mode 100644 index 00000000..8655ee31 --- /dev/null +++ b/src/validate/defaultvalidation.cc @@ -0,0 +1,85 @@ +// +// Copyright (c) 2020, 2021, 2022, 2023 Humanitarian OpenStreetMap Team +// +// This file is part of Underpass. +// +// Underpass is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Underpass is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Underpass. If not, see . +// + +#ifndef __DEFAULTVALIDATION_H__ +#define __DEFAULTVALIDATION_H__ + +#include +#include "utils/yaml.hh" +#include "defaultvalidation.hh" +#include "geospatial.hh" +#include "semantic.hh" +#include "validate.hh" +#include "osm/osmchange.hh" +#include "utils/log.hh" + +using namespace logger; + +namespace defaultvalidation { + +LogFile &dbglogfile = LogFile::getDefaultInstance(); + +DefaultValidation::DefaultValidation(void) {} + +// Check a POI for tags. A node that is part of a way shouldn't have any +// tags, this is to check actual POIs, like a school. +std::shared_ptr +DefaultValidation::checkNode(const osmobjects::OsmNode &node, const std::string &type) +{ + auto status = std::make_shared(node); + status->timestamp = boost::posix_time::microsec_clock::universal_time(); + status->uid = node.uid; + if (yamls.size() == 0) { + log_error("No config files!"); + return status; + } + yaml::Yaml tests = yamls[type]; + semantic::Semantic::checkNode(node, type, tests, status); + + return status; +} + +// This checks a way. A way should always have some tags. Often a polygon +// with no tags is a building. +std::shared_ptr +DefaultValidation::checkWay(const osmobjects::OsmWay &way, const std::string &type) +{ + auto status = std::make_shared(way); + status->timestamp = boost::posix_time::microsec_clock::universal_time(); + status->uid = way.uid; + if (yamls.size() == 0) { + log_error("No config files!"); + return status; + } + yaml::Yaml tests = yamls[type]; + semantic::Semantic::checkWay(way, type, tests, status); + geospatial::Geospatial::checkWay(way, type, tests, status); + boost::geometry::centroid(way.linestring, status->center); + status->source = type; + return status; +} + +}; // namespace defaultvalidation + +#endif // EOF __DEFAULTVALIDATION_H__ + +// Local Variables: +// mode: C++ +// indent-tabs-mode: nil +// End: diff --git a/src/validate/defaultvalidation.hh b/src/validate/defaultvalidation.hh new file mode 100644 index 00000000..d3bf20f2 --- /dev/null +++ b/src/validate/defaultvalidation.hh @@ -0,0 +1,75 @@ +// +// Copyright (c) 2020, 2021, 2022, 2023 Humanitarian OpenStreetMap Team +// +// This file is part of Underpass. +// +// Underpass is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Underpass is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Underpass. If not, see . +// + +/// \file defaultvalidation.hh +/// \brief This file implements the default data validation + +#ifndef __DEFAULTVALIDATION_HH__ +#define __DEFAULTVALIDATION_HH__ + +// This is generated by autoconf +#ifdef HAVE_CONFIG_H +# include "unconfig.h" +#endif + +#include +#include "utils/yaml.hh" + +// MinGW related workaround +#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION + +#include "validate.hh" + +/// \namespace defaultvalidation +namespace defaultvalidation { + +/// \class DefaultValidation +/// \brief This is the plugin class, deprived from the Validate class +class DefaultValidation : public Validate +{ +public: + DefaultValidation(void); + ~DefaultValidation(void) { }; + + /// Check a POI for tags. A node that is part of a way shouldn't have any + /// tags, this is to check actual POIs, like a school. + std::shared_ptr checkNode(const osmobjects::OsmNode &node, const std::string &type); + + /// This checks a way. A way should always have some tags. Often a polygon + /// is a building + std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type); + + // Factory method + static std::shared_ptr create(void) { + return std::make_shared(); + }; +private: + std::map> tests; +}; + +BOOST_DLL_ALIAS(DefaultValidation::create, create_plugin) + +} // EOF defaultvalidation namespace + +#endif // EOF __DEFAULTVALIDATION_HH__ + +// Local Variables: +// mode: C++ +// indent-tabs-mode: nil +// End: diff --git a/src/validate/geospatial.cc b/src/validate/geospatial.cc index 1b2e43a9..79bbbaf2 100644 --- a/src/validate/geospatial.cc +++ b/src/validate/geospatial.cc @@ -20,22 +20,9 @@ #ifndef __GEOSPATIAL_H__ #define __GEOSPATIAL_H__ -#include -#include #include #include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include + #include #include @@ -57,45 +44,61 @@ namespace geospatial { LogFile &dbglogfile = LogFile::getDefaultInstance(); -Geospatial::Geospatial(void) {} - -// Check a POI for tags. A node that is part of a way shouldn't have any -// tags, this is to check actual POIs, like a school. -std::shared_ptr -Geospatial::checkPOI(const osmobjects::OsmNode &node, const std::string &type) -{ - auto status = std::make_shared(node); - return status; -} +Geospatial::Geospatial() {} // This checks a way. A way should always have some tags. Often a polygon // with no tags is a building. std::shared_ptr -Geospatial::checkWay(const osmobjects::OsmWay &way, const std::string &type) +Geospatial::checkWay(const osmobjects::OsmWay &way, const std::string &type, yaml::Yaml &tests, std::shared_ptr &status) { - auto status = std::make_shared(way); + // On non-english numeric locales using decimal separator different than '.' + // this is necessary to parse double strings with std::stod correctly + // without loosing precision + // std::setlocale(LC_NUMERIC, "C"); + setlocale(LC_NUMERIC, "C"); + + if (way.action == osmobjects::remove) { + return status; + } + + // These values are in the config section of the YAML file + auto config = tests.get("config"); + + // if (config.contains_value("overlaps", "yes")) { + // auto allWays = context.getOverlappingWays(); + // if (overlaps(allWays, way)) { + // status->status.insert(overlaping); + // } + // } + + // if (config.contains_value("duplicate", "yes")) { + // auto allWays = context.getOverlappingWays(); + // if (overlaps(allWays, way)) { + // status->status.insert(overlaping); + // } + // } + + if (unsquared(way.linestring)) { + status->status.insert(badgeom); + } + return status; } bool Geospatial::overlaps(const std::list> &allways, osmobjects::OsmWay &way) { - // This test only applies to buildings, as highways often overlap. - // TODO: move logic to a config file - yaml::Yaml tests = yamls["building"]; - if (tests.get("config").contains_value("overlaps", "yes")) { #ifdef TIMING_DEBUG_X - boost::timer::auto_cpu_timer timer("validate::overlaps: took %w seconds\n"); + boost::timer::auto_cpu_timer timer("validate::overlaps: took %w seconds\n"); #endif - if (way.numPoints() <= 1) { - return false; - } - for (auto nit = std::begin(allways); nit != std::end(allways); ++nit) { - osmobjects::OsmWay *oldway = nit->get(); - if (boost::geometry::overlaps(oldway->polygon, way.polygon)) { - if (way.getTagValue("layer") == oldway->getTagValue("layer") && way.id != oldway->id) { - log_error("Building %1% overlaps with %2%", way.id, oldway->id); - return true; - } + if (way.numPoints() <= 1) { + return false; + } + for (auto nit = std::begin(allways); nit != std::end(allways); ++nit) { + osmobjects::OsmWay *oldway = nit->get(); + if (boost::geometry::overlaps(oldway->polygon, way.polygon)) { + if (way.getTagValue("layer") == oldway->getTagValue("layer") && way.id != oldway->id) { + log_error("Building %1% overlaps with %2%", way.id, oldway->id); + return true; } } } @@ -106,29 +109,25 @@ bool Geospatial::duplicate(const std::list> &allways, osmobjects::OsmWay &way) { // This test only applies to buildings, as highways often overlap. // TODO: move logic to a config file - yaml::Yaml tests = yamls["building"]; - if (tests.get("config").contains_value("duplicate", "yes")) { #ifdef TIMING_DEBUG_X - boost::timer::auto_cpu_timer timer("validate::duplicate: took %w seconds\n"); + boost::timer::auto_cpu_timer timer("validate::duplicate: took %w seconds\n"); #endif - if (way.numPoints() <= 1) { - return false; - } - - for (auto nit = std::begin(allways); nit != std::end(allways); ++nit) { - osmobjects::OsmWay *oldway = nit->get(); - std::deque output; - bg::intersection(oldway->polygon, way.polygon, output); - double iarea = 0; - for (auto& p : output) - iarea += bg::area(p); - double wayarea = bg::area(way.polygon); - double iareapercent = (iarea * 100) / wayarea; - if (iareapercent >= 80) { - if (way.getTagValue("layer") == oldway->getTagValue("layer") && way.id != oldway->id) { - log_error("Building %1% duplicate %2%", way.id, oldway->id); - return true; - } + if (way.numPoints() <= 1) { + return false; + } + for (auto nit = std::begin(allways); nit != std::end(allways); ++nit) { + osmobjects::OsmWay *oldway = nit->get(); + std::deque output; + bg::intersection(oldway->polygon, way.polygon, output); + double iarea = 0; + for (auto& p : output) + iarea += bg::area(p); + double wayarea = bg::area(way.polygon); + double iareapercent = (iarea * 100) / wayarea; + if (iareapercent >= 80) { + if (way.getTagValue("layer") == oldway->getTagValue("layer") && way.id != oldway->id) { + log_error("Building %1% duplicate %2%", way.id, oldway->id); + return true; } } } @@ -142,6 +141,9 @@ Geospatial::unsquared( double max_angle ) { const int num_points = boost::geometry::num_points(way); + double last_angle = -1; + double max_angle_diff = 0; + bool unsquared = false; for(int i = 0; i < num_points - 1; i++) { // Three points int a,b,c; @@ -166,14 +168,24 @@ Geospatial::unsquared( double y3 = boost::geometry::get<1>(way[c]); double angle = geo::Geo::calculateAngle(x1,y1,x2,y2,x3,y3); + if (last_angle != -1) { + double diff = abs(angle - last_angle); + if (diff > max_angle_diff) { + max_angle_diff = diff; + } + } + last_angle = angle; if ( (angle > max_angle || angle < min_angle) && (angle < 179 || angle > 181) ) { - return true; + unsquared = true; } } + if (unsquared && !(num_points > 5 && max_angle_diff < 3)) { + return true; + } return false; }; diff --git a/src/validate/geospatial.hh b/src/validate/geospatial.hh index 58a7c4ad..daec1396 100644 --- a/src/validate/geospatial.hh +++ b/src/validate/geospatial.hh @@ -18,7 +18,7 @@ // /// \file geospatial.hh -/// \brief This file implements the data validation used by HOT +/// \brief Geospatial validation #ifndef __GEOSPATIAL_HH__ #define __GEOSPATIAL_HH__ @@ -28,61 +28,28 @@ # include "unconfig.h" #endif -#include -#include -#include #include -#include - -#include -#include -#include -#include -#include -#include -#include -using namespace boost::posix_time; -using namespace boost::gregorian; - -#include "utils/yaml.hh" - -// MinGW related workaround -#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION - +#include "osm/osmobjects.hh" #include "validate.hh" +#include "utils/yaml.hh" /// \namespace geospatial namespace geospatial { /// \class Geospatial /// \brief This is the plugin class, deprived from the Validate class -class Geospatial : public Validate +class Geospatial { public: - Geospatial(void); + Geospatial(); ~Geospatial(void) { }; - - /// Check a POI for tags. A node that is part of a way shouldn't have any - /// tags, this is to check actual POIs, like a school. - std::shared_ptr checkPOI(const osmobjects::OsmNode &node, const std::string &type); - - /// This checks a way. A way should always have some tags. Often a polygon - /// is a building - std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type); - - // Factory method - static std::shared_ptr create(void) { - return std::make_shared(); - }; + static std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type, yaml::Yaml &tests, std::shared_ptr &status); private: - std::map> tests; - bool unsquared(const linestring_t &way, double min_angle = 89, double max_angle = 91); - bool duplicate(const std::list> &allways, osmobjects::OsmWay &way); - bool overlaps(const std::list> &allways, osmobjects::OsmWay &way); + static bool unsquared(const linestring_t &way, double min_angle = 89, double max_angle = 91); + static bool duplicate(const std::list> &allways, osmobjects::OsmWay &way); + static bool overlaps(const std::list> &allways, osmobjects::OsmWay &way); }; -BOOST_DLL_ALIAS(Geospatial::create, create_plugin) - } // EOF geospatial namespace #endif // EOF __GEOSPATIAL_HH__ diff --git a/src/validate/semantic.cc b/src/validate/semantic.cc index 057ac84e..1c06af4f 100644 --- a/src/validate/semantic.cc +++ b/src/validate/semantic.cc @@ -31,11 +31,8 @@ #include #include -#include #include #include -#include -#include #include #include @@ -57,7 +54,35 @@ namespace semantic { LogFile &dbglogfile = LogFile::getDefaultInstance(); -Semantic::Semantic(void) {} +Semantic::Semantic() {} + +// Check a tag for typical errors + +void +Semantic::checkTag(const std::string &key, const std::string &value, std::shared_ptr &status) +{ + // log_trace("Semantic::checkTag(%1%, %2%)", key, value); + // Check for an empty value + if (!key.empty() && value.empty()) { + log_debug("WARNING: empty value for tag \"%1%\"", key); + status->status.insert(badvalue); + } + // Check for a space in the tag key + if (key.find(' ') != std::string::npos) { + log_error("WARNING: spaces in tag key \"%1%\"", key); + status->status.insert(badvalue); + } + // Check for single quotes in the tag value + if (value.find('\'') != std::string::npos) { + log_error("WARNING: single quote in tag value \"%1%\"", value); + status->status.insert(badvalue); + } + // Check for single quotes in the tag value + if (value.find('\"') != std::string::npos) { + log_error("WARNING: double quote in tag value \"%1%\"", value); + status->status.insert(badvalue); + } +} bool Semantic::isValidTag(const std::string &key, const std::string &value, yaml::Node tags) { if (tags.contains_value(key, value) || @@ -79,16 +104,8 @@ bool Semantic::isRequiredTag(const std::string &key, yaml::Node required_tags) { // Check a POI for tags. A node that is part of a way shouldn't have any // tags, this is to check actual POIs, like a school. std::shared_ptr -Semantic::checkPOI(const osmobjects::OsmNode &node, const std::string &type) +Semantic::checkNode(const osmobjects::OsmNode &node, const std::string &type, yaml::Yaml &tests, std::shared_ptr &status) { - auto status = std::make_shared(node); - status->timestamp = boost::posix_time::microsec_clock::universal_time(); - status->uid = node.uid; - - if (yamls.size() == 0) { - log_error("No config files!"); - return status; - } if (node.tags.size() == 0) { status->status.insert(notags); return status; @@ -97,8 +114,6 @@ Semantic::checkPOI(const osmobjects::OsmNode &node, const std::string &type) return status; } - // Configuration for validation - yaml::Yaml tests = yamls[type]; // List of valid tags to be validated auto tags = tests.get("tags"); @@ -118,24 +133,19 @@ Semantic::checkPOI(const osmobjects::OsmNode &node, const std::string &type) if (isRequiredTag(vit->first, required_tags)) { tagexists++; } - checkTag(vit->first, vit->second); + checkTag(vit->first, vit->second, status); } - if (tagexists == required_tags.children.size()) { - status->status.insert(complete); - } else { + if (tagexists != required_tags.children.size()) { status->status.insert(incomplete); } - if (status->status.size() == 0) { - status->status.insert(correct); - } return status; } // This checks a way. A way should always have some tags. Often a polygon // with no tags is a building. std::shared_ptr -Semantic::checkWay(const osmobjects::OsmWay &way, const std::string &type) +Semantic::checkWay(const osmobjects::OsmWay &way, const std::string &type, yaml::Yaml &tests, std::shared_ptr &status) { // On non-english numeric locales using decimal separator different than '.' // this is necessary to parse double strings with std::stod correctly @@ -143,14 +153,6 @@ Semantic::checkWay(const osmobjects::OsmWay &way, const std::string &type) // std::setlocale(LC_NUMERIC, "C"); setlocale(LC_NUMERIC, "C"); - auto status = std::make_shared(way); - status->timestamp = boost::posix_time::microsec_clock::universal_time(); - status->uid = way.uid; - - if (yamls.size() == 0) { - log_error("No config files!"); - return status; - } if (way.tags.size() == 0) { status->status.insert(notags); return status; @@ -159,8 +161,6 @@ Semantic::checkWay(const osmobjects::OsmWay &way, const std::string &type) return status; } - yaml::Yaml tests = yamls[type]; - std::string key; // List of valid tags to be validated auto tags = tests.get("tags"); @@ -178,83 +178,23 @@ Semantic::checkWay(const osmobjects::OsmWay &way, const std::string &type) int tagexists = 0; for (auto vit = std::begin(way.tags); vit != std::end(way.tags); ++vit) { - if (!isValidTag(vit->first, vit->second, tags)) { - status->status.insert(badvalue); - status->values.insert(vit->first + "=" + vit->second); - } - if (isRequiredTag(vit->first, required_tags)) { - tagexists++; - } - checkTag(vit->first, vit->second); + if (!isValidTag(vit->first, vit->second, tags)) { + status->status.insert(badvalue); + status->values.insert(vit->first + "=" + vit->second); + } + if (isRequiredTag(vit->first, required_tags)) { + tagexists++; + } + // checkTag(vit->first, vit->second, status); } - if (tagexists == required_tags.children.size()) { - status->status.insert(complete); - } else { + if (tagexists != required_tags.children.size()) { status->status.insert(incomplete); } return status; } -// Check a tag for typical errors -std::shared_ptr -Semantic::checkTag(const std::string &key, const std::string &value) -{ - auto status = std::make_shared(); - // log_trace("Semantic::checkTag(%1%, %2%)", key, value); - // Check for an empty value - if (!key.empty() && value.empty()) { - log_debug("WARNING: empty value for tag \"%1%\"", key); - status->status.insert(badvalue); - } - // Check for a space in the tag key - if (key.find(' ') != std::string::npos) { - log_error("WARNING: spaces in tag key \"%1%\"", key); - status->status.insert(badvalue); - } - // Check for single quotes in the tag value - if (value.find('\'') != std::string::npos) { - log_error("WARNING: single quote in tag value \"%1%\"", value); - status->status.insert(badvalue); - } - // Check for single quotes in the tag value - if (value.find('\"') != std::string::npos) { - log_error("WARNING: double quote in tag value \"%1%\"", value); - status->status.insert(badvalue); - } - return status; -} - -// Check a OSM Change for typical errors -std::vector -Semantic::checkOsmChange(const std::string &xml, const std::string &check) { - osmchange::OsmChangeFile ocf; - std::stringstream _xml(xml); - ocf.readXML(_xml); - std::vector result; - for (auto it = std::begin(ocf.changes); it != std::end(ocf.changes); ++it) { - osmchange::OsmChange *change = it->get(); - for (auto wit = std::begin(change->ways); wit != std::end(change->ways); ++wit) { - osmobjects::OsmWay *way = wit->get(); - if (!way->containsKey(check)) { - continue; - } - auto status = checkWay(*way, check); - result.push_back(*status); - } - for (auto nit = std::begin(change->nodes); nit != std::end(change->nodes); ++nit) { - osmobjects::OsmNode *node = nit->get(); - if (!node->containsKey(check)) { - continue; - } - auto status = checkPOI(*node, check); - result.push_back(*status); - } - } - return result; -} - }; // namespace semantic #endif // EOF __SEMANTIC_H__ diff --git a/src/validate/semantic.hh b/src/validate/semantic.hh index 6f62896c..14f93e11 100644 --- a/src/validate/semantic.hh +++ b/src/validate/semantic.hh @@ -35,20 +35,14 @@ #include #include -#include -#include #include #include #include -#include using namespace boost::posix_time; using namespace boost::gregorian; #include "utils/yaml.hh" -// MinGW related workaround -#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION - #include "validate.hh" /// \namespace semantic @@ -56,38 +50,19 @@ namespace semantic { /// \class Semantic /// \brief This is the plugin class, deprived from the Validate class -class Semantic : public Validate +class Semantic { public: - Semantic(void); + Semantic(); ~Semantic(void) { }; - - /// Check a POI for tags. A node that is part of a way shouldn't have any - /// tags, this is to check actual POIs, like a school. - std::shared_ptr checkPOI(const osmobjects::OsmNode &node, const std::string &type); - - /// This checks a way. A way should always have some tags. Often a polygon - /// is a building - std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type); - - /// Check a tag - std::shared_ptr checkTag(const std::string &key, const std::string &value); - - /// Check a set of changes - std::vector checkOsmChange(const std::string &xml, const std::string &check); - - // Factory method - static std::shared_ptr create(void) { - return std::make_shared(); - }; + static std::shared_ptr checkNode(const osmobjects::OsmNode &node, const std::string &type, yaml::Yaml &tests, std::shared_ptr &status); + static std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type, yaml::Yaml &tests, std::shared_ptr &status); private: - std::map> tests; - bool isValidTag(const std::string &key, const std::string &value, yaml::Node tags); - bool isRequiredTag(const std::string &key, yaml::Node required_tags); + static bool isValidTag(const std::string &key, const std::string &value, yaml::Node tags); + static bool isRequiredTag(const std::string &key, yaml::Node required_tags); + static void checkTag(const std::string &key, const std::string &value, std::shared_ptr &status); }; -BOOST_DLL_ALIAS(Semantic::create, create_plugin) - } // EOF semantic namespace #endif // EOF __SEMANTIC_HH__ diff --git a/src/validate/validate.hh b/src/validate/validate.hh index 5d5cdf12..6f96b674 100644 --- a/src/validate/validate.hh +++ b/src/validate/validate.hh @@ -183,7 +183,7 @@ class BOOST_SYMBOL_VISIBLE Validate { for (auto &file: std::filesystem::recursive_directory_iterator(path)) { std::filesystem::path config = file.path(); if (config.extension() == ".yaml") { - log_debug("Loading: %s", config.stem()); + std::cout << "Loading: " << config.stem() << std::endl; yaml::Yaml yaml; yaml.read(config.string()); if (!config.stem().empty()) { @@ -196,25 +196,8 @@ class BOOST_SYMBOL_VISIBLE Validate { virtual ~Validate(void){}; // Validate(std::vector> &changes) {}; - /// Check a POI for tags. A node that is part of a way shouldn't have any - /// tags, this is to check actual POIs, like a school. - virtual std::shared_ptr checkGeometry(const osmobjects::OsmNode &node, const std::string &type) = 0; - /// This checks a way. A way should always have some tags. Often a polygon - /// is a building - virtual std::shared_ptr checkGeometry(const osmobjects::OsmWay &way, const std::string &type) = 0; - - virtual std::shared_ptr checkSemantic(const osmobjects::OsmWay &way, const std::string &type) = 0; - virtual std::shared_ptr checkSemantic(const osmobjects::OsmWay &node, const std::string &type) = 0; - - std::shared_ptr checkNode(const osmobjects::OsmWay &node, const std::string &type) { - auto status = std::make_shared(node); - auto geometryStatus = checkGeometry(node, type); - auto semanticStatus = checkSemantic(node, type); - } - std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type) { - // checkGeometry - // checkSemantic - } + virtual std::shared_ptr checkNode(const osmobjects::OsmNode &node, const std::string &type) = 0; + virtual std::shared_ptr checkWay(const osmobjects::OsmWay &way, const std::string &type) = 0; yaml::Yaml &operator[](const std::string &key) { return yamls[key]; }; diff --git a/src/wrappers/python.cc b/src/wrappers/python.cc index 83ac89ad..c3b0efbb 100644 --- a/src/wrappers/python.cc +++ b/src/wrappers/python.cc @@ -25,7 +25,7 @@ #define BOOST_BIND_GLOBAL_PLACEHOLDERS 1 #include -#include "validate/hotosm.hh" +// #include "validate/defaultvalidation.hh" #include "validate/validate.hh" #include "osm/osmobjects.hh" #include "osm/osmchange.hh" @@ -51,19 +51,19 @@ std::map results = { {duplicate, "duplicate"} }; -ValidateStatus* checkPOI(hotosm::Hotosm& self, const osmobjects::OsmNode &node, const std::string &type) { - auto _v = self.checkPOI(node, type); - ValidateStatus* v = new ValidateStatus(); - v->status = _v->status; - return v; -} +// ValidateStatus* checkNode(defaultvalidation::DefaultValidation& self, const osmobjects::OsmNode &node, const std::string &type) { +// // auto _v = self.checkNode(node, type); +// ValidateStatus* v = new ValidateStatus(); +// // v->status = _v->status; +// return v; +// } -ValidateStatus* checkWay(hotosm::Hotosm& self, const osmobjects::OsmWay &way, const std::string &type) { - auto _v = self.checkWay(way, type); - ValidateStatus* v = new ValidateStatus(); - v->status = _v->status; - return v; -} +// ValidateStatus* checkWay(defaultvalidation::DefaultValidation& self, const osmobjects::OsmWay &way, const std::string &type) { +// // auto _v = self.checkWay(way, type); +// ValidateStatus* v = new ValidateStatus(); +// // v->status = _v->status; +// return v; +// } std::string dumpJSON(ValidateStatus& self) { std::string output = ""; @@ -93,29 +93,29 @@ std::string dumpJSON(ValidateStatus& self) { return output; } -std::string checkOsmChange(hotosm::Hotosm& self, const std::string &xml, const std::string &check) { - auto result = self.checkOsmChange(xml, check); - std::string output = "[ "; - for (auto it = std::begin(result); it != std::end(result); ++it) { - if ((*it).status.size() > 0) { - output += dumpJSON(*it) + ","; - } - } - output.erase(output.size() - 1); - output += " ]"; - return output; -} +// std::string checkOsmChange(defaultvalidation::DefaultValidation& self, const std::string &xml, const std::string &check) { +// auto result = self.checkOsmChange(xml, check); +// std::string output = "[ "; +// for (auto it = std::begin(result); it != std::end(result); ++it) { +// if ((*it).status.size() > 0) { +// output += dumpJSON(*it) + ","; +// } +// } +// output.erase(output.size() - 1); +// output += " ]"; +// return output; +// } BOOST_PYTHON_MODULE(underpass) { // - using namespace hotosm; - class_("Validate") - .def("checkTag", &Hotosm::checkTag) - .def("checkWay", &checkWay, boost::python::return_value_policy()) - .def("checkPOI", &checkPOI, boost::python::return_value_policy()) - .def("overlaps", &Hotosm::overlaps) - .def("checkOsmChange", &checkOsmChange); + // using namespace defaultvalidation; + // class_("Validate") + // // .def("checkTag", &DefaultValidation::checkTag) + // .def("checkWay", &checkWay, boost::python::return_value_policy()) + // .def("checkNode", &checkNode, boost::python::return_value_policy()); + // // .def("overlaps", &DefaultValidation::overlaps); + // // .def("checkOsmChange", &checkOsmChange); class_("ValidateStatus") .def("hasStatus", &ValidateStatus::hasStatus) From 549f4535ed71bfd0cc6e102747d797a2c0005350 Mon Sep 17 00:00:00 2001 From: Emillio Mariscal Date: Tue, 7 Nov 2023 20:48:11 -0300 Subject: [PATCH 3/4] Remove unused code, verbosity --- python/restapi/main.py | 1 - src/data/pq.cc | 2 -- src/osm/osmchange.cc | 2 -- 3 files changed, 5 deletions(-) diff --git a/python/restapi/main.py b/python/restapi/main.py index 379ff6d3..6bb37cef 100644 --- a/python/restapi/main.py +++ b/python/restapi/main.py @@ -233,7 +233,6 @@ def getNodesList(request: RawRequest): @app.post("/raw/allList") def getAllList(request: RawRequest): - print("request.status", request.status) results = rawer.getAllList( area = request.area or None, tags = request.tags or "", diff --git a/src/data/pq.cc b/src/data/pq.cc index 7018e815..8b82ef25 100644 --- a/src/data/pq.cc +++ b/src/data/pq.cc @@ -25,8 +25,6 @@ #include "data/pq.hh" #include #include -#include -#include #include #include #include diff --git a/src/osm/osmchange.cc b/src/osm/osmchange.cc index 0a064878..76ec8164 100644 --- a/src/osm/osmchange.cc +++ b/src/osm/osmchange.cc @@ -27,8 +27,6 @@ #include #include #include -#include -#include #include #include #include From 6b5677a5096cb70a8ff5bb4c5ed6333893b13313 Mon Sep 17 00:00:00 2001 From: Emillio Mariscal Date: Wed, 8 Nov 2023 11:39:41 -0300 Subject: [PATCH 4/4] Fix for parse tags from DB response, change 'overlaping' to 'overlapping', less verbose --- config/validate/building.yaml | 1440 +---------------- python/dbapi/api/raw.py | 1 - setup/underpass.sql | 2 +- src/bootstrap/bootstrap.cc | 2 +- src/raw/queryraw.cc | 33 +- src/replicator/threads.cc | 4 +- src/testsuite/libunderpass.all/stats-test.cc | 1 - .../libunderpass.all/test-playground.cc | 33 - src/testsuite/libunderpass.all/val-test.cc | 34 +- .../testdata/validation/config/building.yaml | 16 +- src/validate/defaultvalidation.cc | 4 +- src/validate/geospatial.cc | 39 +- src/validate/queryvalidate.cc | 2 +- src/validate/semantic.cc | 69 +- src/validate/validate.hh | 5 +- src/wrappers/python.cc | 2 +- 16 files changed, 120 insertions(+), 1567 deletions(-) diff --git a/config/validate/building.yaml b/config/validate/building.yaml index 041a252a..98b2e609 100644 --- a/config/validate/building.yaml +++ b/config/validate/building.yaml @@ -1,1440 +1,14 @@ config: - - minangle: - - 70 - - maxangle: - - 110 - - anglethreshold: - - 19 - - overlaps: + - badgeom: - yes - - duplicate: + - badgeom_minangle: + - 89 + - badgeom_maxangle: + - 91 + - badvalue: - yes - -tags: - - building: - - apartments - - barracks - - bungalow - - cabin - - detached - - dormitory - - farm - - ger - - hotel - - house - - houseboat - - residential - - semidetached_house - - static_caravan - - stilt_house - - terrace - - tree_house - - commercial - - industrial - - kiosk - - office - - retail - - supermarket - - warehouse - - cathedral - - chapel - - church - - kingdom_hall - - monastery - - mosque - - presbytery - - religious - - shrine - - synagogue - - temple - - bakehouse - - bridge - - civic - - college - - fire_station - - government - - gatehouse - - hospital - - kindergarten - - public - - school - - toilets - - train_station - - transportation - - university - - barn - - conservatory - - cowshed - - farm_auxiliary - - greenhouse - - slurry_tank - - stable - - sty - - grandstand - - pavilion - - riding_hall - - sports_hall - - stadium - - hangar - - hut - - shed - - carport - - garage - - garages - - parking - - digester - - service - - transformer_tower - - water_tower - - storage_tank - - silo - - beach_hut - - bunker - - castle - - construction - - container - - military - - roof - - ruins - - tent - - yes - - - building:levels - - - building:structure: - - confined_masonry - - steel_frame - - wood_frame - - bamboo_frame - - reinforced_masonry - - unreinforced_masonry - - plastered - - RCC_with_beam - - non_engineered_reinforced_concrete - - engineered_reinforced_concrete - - load_bearing_brick_wall_in_cement_mortar - - brick - - cement_blocks - - steel_frame - - concrete - - - building:material: - - cement_block - - brick - - plaster - - wood - - concrete - - metal - - steel - - stone - - glass - - mirror - - mud - - masonry - - tin - - plastic - - timber_framing - - sandstone - - clay - - reed - - loam - - marble - - copper - - slate - - vinyl - - limestone - - tiles - - metal_plates - - bamboo - - adobe - - rammed_earth - - solar_panels - - tyres - - - roof:material: - - roof_tiles - - metal - - concrete - - tar_paper - - asbestos - - eternit - - glass - - metal_sheet - - slate - - tin - - grass - - copper - - thatch - - gravel - - stone - - wood - - plastic - - asphalt - - zinc - - sandstone - - bamboo - - palm_leaves - - banana_leaves - - solar_panels - - titanium - - - roof:shape: - - gabled - - round - - saltbox - - double_saltbox - - quadruple_saltbox - - sawtooth - - cone - - conical - - side_hipped - - lean_to - - shed - - gabled_row - - crosspitched - - parabolic - - many - - gabled - - flat - - hipped - - pyramidal - - skillion - - half-hipped - - gambrel - - mansard - - dome - - onion - - roof:orientation - - along - - across - - roof:height - - roof:angle - - roof:levels - - roof:direction - - roof:material - - roof:colour - - - floor:material: - - plaster - - brick - - wood - - concrete - - glass - - stone - - asphalt - - metal - - marble - - mdf - - timber_framing - - - building:condition: - - good - - average - - poor - - disused - - - building:colour - - building:fireproof: + - incomplete: - yes - - no - - building:flats - - building:levels - - building:min_level - - building:part - - building:soft_storey: - - yes - - no - - reinforced - - - entrance: - - yes - - main - - exit - - service - - emergency - - height - - max_level - - min_level - - non_existent_levels - - start_date - - - shop: - - alcohol - - art - - bakery - - beauty - - beverages - - bicycle - - books - - butcher - - car - - car_parts - - car_repair - - chemist - - clothes - - convenience - - copyshop - - cosmetics - - charcoal - - electronics - - farm - - furniture - - general - - greengrocer - - hairdresser - - hardware - - houseware - - jewellery - - kiosk - - mobile_phone - - pastry - - shoes - - stationary - - supermarket - - tailor - - tea - - department_store - - general - - mall - - hardware - - laundry - - trade - - office: - - accountant - - administrative - - advertising_agency - - architect - - association - - chamber - - charity - - company - - construction_company - - consulting - - courier - - coworking - - diplomatic - - educational_institution - - employment_agency - - energy_supplier - - engineer - - estate_agent - - financial - - financial_advisor - - forestry - - foundation - - geodesist - - government - - graphic_design - - guide - - harbour_master - - insurance - - it - - lawyer - - logistics - - moving_company - - newspaper - - ngo - - notary - - politician - - political_party - - property_management - - quango - - religion - - research - - security - - surveyor - - tax_advisor - - telecommunication - - therapist - - travel_agent - - tutoring - - union - - visa - - water_utility - - yes - - religious: - - church - - mosque - - temple - - shrine - - cathedral - - chapel - - synagogue - - religion: - - muslim - - hindu - - christian - - buddhist - - jewish - - bahai - - capacity_persons: - - <50 - - 50-100 - - 100-250 - - 250-500 - - >500 - - denomination: - - gelug - - jishu - - jodo_shinshu - - jodo_shu - - nichiren - - nyingma - - obaku - - pure_land - - rinzai - - risshu - - shingon_shu - - soto - - tiantai - - tibetan - - vajrayana - - won - - yogacara - - yuzu_nembutsu - - zen - - thai_mahanikaya - - thai_thammayut - - catholic - - armenian_catholic - - chaldean_catholic - - coptic_catholic - - eritrean_catholic - - ethiopian_catholic - - greek_catholic - - hungarian_greek_catholic - - maronite - - polish_catholic - - roman_catholic - - romanian_catholic - - syriac_catholic - - syro-malabar_catholic - - ukrainian_greek_catholic - - orthodox - - antiochian_orthodox - - armenian_apostolic - - bulgarian_orthodox - - eritrean_orthodox - - ethiopian_orthodox - - coptic_orthodox - - georgian_orthodox - - greek_orthodox - - macedonian_orthodox - - old_believers - - romanian_orthodox - - russian_orthodox - - serbian_orthodox - - syriac_orthodox - - ukrainian_orthodox - - protestant - - adventist - - anglican - - baptist - - disciples_of_christ - - episcopal - - evangelical - - evangelical_covenant - - exclusive_brethren - - lutheran - - mennonite - - methodist - - moravian - - pentecostal - - presbyterian - - quaker - - reformed - - uniting - - polish_national_catholic - - african_methodist_episcopal - - african_methodist_episcopal_zion - - alliance - - apostolic_faith - - assemblies_of_god - - calvinistic_methodist - - catholic_apostolic - - church_of_god_in_christ - - church_of_scotland - - churches_of_christ - - czechoslovak_hussite - - disciples_of_christ - - dutch_reformed - - evangelical_covenant - - evangelical_free_church_of_america - - evangelical_lutheran - - evangelical_free_church_of_france - - exclusive_brethren - - foursquare - - free_church_of_scotland - - living_waters_church - - mission_covenant_church_of_sweden - - moravian - - mormon - - nazarene - - new_frontiers - - orthodox_presbyterian_church - - pkn - - remonstrant - - salvation_army - - scottish_episcopal - - seventh_day_adventist - - strict_baptist - - temple_society_australia - - united - - united_free_church_of_scotland - - united_reformed - - uniting - - united_methodist - - united_church_of_christ - - welsh_baptist - - welsh_independent - - apostolic - - assyrian - - catholic_mariavite - - charismatic - - christian_community - - christ_scientist - - church_of_christ - - congregational - - ecumenical - - fsspx - - harrist - - iglesia_ni_cristo - - jehovahs_witness - - kimbanguist - - la_luz_del_mundo - - liberal_catholic - - mariavite - - messianic_jewish - - new_apostolic - - nondenominational - - old_catholic - - philippine_independent - - simultaneum - - spiritist - - shaktism - - hare_krishna - - vaishnavism - - shaivism - - smartism - - nondenominational - - ahmadiyya - - alevi - - bektashi - - ibadi - - ismaili - - shia - - sunni - - sufi - - digambara - - svetambara - - nondenominational - - unaffiliated - - ashkenazi - - buchari - - conservative - - hasidic - - kabbalistic - - karaite - - lubavitch - - mizrachi - - modern_orthodox - - neo_orthodox - - orthodox - - reconstructionist - - reform - - progressive - - liberal - - samaritan - - sephardi - - traditional - - unity - - asatru - - celtic - - greco-roman - - slavic - - wicca - - quanzhen - - zhengyi - - irani - - parsi - - water_source: - - water_works - - manual_pump - - powered_pump - - groundwater - - historic: - - archaeological_site - - building - - fort - - monument - - area - - housing: - - residential - - hotel - - camp_site - - camp_pitch - - apartments - - toilet - - service: - - car_repair - - electronics_repair - - pump_station - - copyshop - - beauty - - service - - tailor - - cuisine: - - afghan - - african - - american - - arab - - argentinian - - armenian - - asian - - australian - - austrian - - balkan - - bangladeshi - - basque - - bavarian - - belgian - - bolivian - - brazilian - - british - - bulgarian - - cajun - - cambodian - - cantonese - - caribbean - - chinese - - colombian - - croatian - - cuban - - czech - - danish - - dutch - - egyptian - - ethiopian - - european - - filipino - - french - - georgian - - german - - greek - - hawaiian - - hungarian - - indian - - indonesian - - irish - - italian - - jamaican - - japanese - - jewish - - korean - - lao - - latin_american - - lebanese - - malagasy - - malaysian - - mediterranean - - mexican - - middle_eastern - - mongolian - - moroccan - - nepalese - - oriental - - pakistani - - persian - - peruvian - - polish - - portuguese - - romanian - - russian - - senegalese - - serbian - - southern - - spanish - - sri_lankan - - swedish - - swiss - - syrian - - taiwanese - - tex-mex - - thai - - tibetan - - turkish - - ukrainian - - uzbek - - venezuelan - - vietnamese - - western - - açaí - - bagel - - beef - - beef_bowl - - beef_noodle - - bougatsa - - bubble_tea - - burger - - cake - - chicken - - chili - - chocolate - - churro - - coffee_shop - - couscous - - crepe - - curry - - donut - - dumpling - - empanada - - falafel - - fish - - fish_and_chips - - fondue - - fried_chicken - - fries - - frozen_yogurt - - gyoza - - gyros - - hot_dog - - hotpot - - ice_cream - - juice - - kebab - - meat - - noodle - - pancake - - pasta - - pastry - - piadina - - pie - - pita - - pizza - - poke - - potato - - pretzel - - ramen - - salad - - sandwich - - sausage - - savory_pancakes - - seafood - - shawarma - - smoothie - - smørrebrød - - soba - - soup - - souvlaki - - steak - - sushi - - tacos - - takoyaki - - tea - - udon - - waffle - - wings - - yakitori - - bakery - - bar&grill - - barbecue - - bistro - - brasserie - - breakfast - - brunch - - buffet - - buschenschank - - cafe - - deli - - dessert - - diner - - fast_food - - fine_dining - - fried_food - - friture - - fusion - - grill - - heuriger - - international - - local - - lunch - - pub - - regional - - snack - - steak_house - - tapas - - yakiniku - - amenity: - - bar - - cafe - - fast_food - - food_court - - ice_cream - - pub - - restaurant - - college - - driving_school - - kindergarten - - language_school - - library - - toy_library - - training - - music_school - - school - - university - - bus_station - - car_rental - - car_sharing - - car_wash - - vehicle_inspection - - ferry_terminal - - fuel - - parking - - bank - - bureau_de_change - - baby_hatch - - clinic - - dentist - - doctors - - hospital - - nursing_home - - pharmacy - - social_facility - - veterinary - - arts_centre - - brothel - - casino - - cinema - - community_centre - - conference_centre - - events_venue - - gambling - - love_hotel - - nightclub - - planetarium - - public_bookcase - - social_centre - - stripclub - - studio - - swingerclub - - theatre - - courthouse - - fire_station - - police - - post_depot - - post_office - - prison - - ranger_station - - townhall - - dressing_room - - give_box - - mailroom - - parcel_locker - - shelter - - toilets - - recycling - - waste_disposal - - waste_transfer_station - - animal_boarding - - animal_breeding - - animal_shelter - - baking_oven - - childcare - - clock - - crematorium - - funeral_hall - - hunting_stand - - internet_cafe - - marketplace - - monastery - - place_of_mourning - - place_of_worship - - public_building - - refugee_site - - tourism: - - camp_site - - taxi - - camp pitch - - caravan_site - - artwork - - gallery - - museum - - zoo - - attraction - - guest_house - - hotel - - hostel - - generator:source: - - grid - - generator - - solar - - hydro - - ref:bag - - addr:housenumber - - addr:housename - - addr:flats - - addr:conscriptionnumber - - addr:street - - addr:place - - addr:postcode - - addr:city - - addr:country - - addr:postbox - - addr:full - - addr:hamlet - - addr:suburb - - addr:subdistrict - - addr:district - - addr:province - - addr:state - - addr:county - - addr:interpolation - - addr:inclusion - - addr:door - - addr:unit - - addr:flats - - addr:floor - - addr:block - - addr:block_number - - roof:colour - - roof:height - - layer - - name - - name:left - - name:right - - int_name - - loc_name - - nat_name - - official_name - - old_name - - reg_name - - short_name - - sorting_name - - alt_name - - noname - - name:ab - - name:ace - - name:ady - - name:af - - name:ak - - name:alt - - name:am - - name:an - - name:ang - - name:ar - - name:arc - - name:as - - name:aus - - name:av - - name:ay - - name:az - - name:ba - - name:be - - name:bg - - name:bh - - name:bi - - name:bm - - name:bn - - name:bo - - name:br - - name:bru - - name:bs - - name:bug - - name:ca - - name:car - - name:cdo - - name:ce - - name:ceb - - name:ch - - name:chm - - name:chr - - name:chy - - name:co - - name:cs - - name:csb - - name:cu - - name:cv - - name:cy - - name:da - - name:de - - name:dsb - - name:dv - - name:dyu - - name:dz - - name:ee - - name:el - - name:en - - name:eo - - name:es - - name:et - - name:etymology - - name:etymology:wikidata - - name:etymology:wikipedia - - name:eu - - name:fa - - name:ff - - name:fi - - name:fo - - name:fr - - name:frr - - name:fur - - name:fy - - name:ga - - name:gcf - - name:gd - - name:gem - - name:gl - - name:gn - - name:grc - - name:gsw - - name:gu - - name:gv - - name:ha - - name:haw - - name:hi - - name:hif - - name:hop - - name:hr - - name:hsb - - name:ht - - name:hu - - name:hy - - name:ia - - name:id - - name:ie - - name:ig - - name:ilo - - name:inh - - name:io - - name:is - - name:it - - name:iu - - name:ja - - name:ja-Latn - - name:jbo - - name:jv - - name:ka - - name:ka-Latn - - name:kaa - - name:kab - - name:kbd - - name:kg - - name:kk - - name:kl - - name:km - - name:kmr - - name:kn - - name:ko - - name:koi - - name:kr - - name:krc - - name:krl - - name:ks - - name:ksh - - name:ku - - name:kum - - name:kv - - name:kw - - name:ky - - name:la - - name:lad - - name:language - - name:lb - - name:lbe - - name:left - - name:lez - - name:lg - - name:li - - name:lmo - - name:ln - - name:lo - - name:lrc - - name:lt - - name:lv - - name:mdf - - name:mg - - name:mhr - - name:mi - - name:min - - name:mk - - name:ml - - name:mn - - name:mos - - name:mr - - name:ms - - name:mt - - name:mwl - - name:my - - name:myv - - name:na - - name:nap - - name:nb - - name:ne - - name:nl - - name:nn - - name:no - - name:nov - - name:nso - - name:oc - - name:om - - name:or - - name:pa - - name:pag - - name:pap - - name:pfl - - name:pih - - name:pjt - - name:pl - - name:pnb - - name:prefix - - name:pronunciation - - name:ps - - name:pt - - name:pwn - - name:qu - - name:right - - name:rm - - name:rn - - name:ru - - name:rue - - name:rw - - name:sa - - name:sah - - name:sc - - name:scn - - name:sco - - name:sd - - name:se - - name:sg - - name:shn - - name:si - - name:signed - - name:sk - - name:skr - - name:sl - - name:sm - - name:sma - - name:sn - - name:so - - name:sq - - name:sr - - name:ss - - name:st - - name:su - - name:sv - - name:sw - - name:syc - - name:szl - - name:ta - - name:te - - name:tet - - name:tg - - name:th - - name:ti - - name:tk - - name:tl - - name:tlh - - name:tn - - name:to - - name:tpi - - name:tr - - name:ts - - name:tt - - name:tw - - name:ty - - name:udm - - name:ug - - name:uk - - name:ur - - name:uz - - name:vi - - name:vi-Hani - - name:vls - - name:vo - - name:wa - - name:war - - name:wikipedia - - name:wo - - name:xmf - - name:yi - - name:yo - - name:za - - name:zu - - - stars - - opening_hours - - operator - - operator:type: - - private - - public - - government - - community - - consortium - - cooperative - - military - - ngo - - religious - - charitable - - leisure: - - adult_gaming_centre - - amusement_arcade - - bandstand - - bird_hide - - bowling_alley - - dance - - escape_game - - fitness_centre - - hackerspace - - ice_rink - - sports_centre - - sports_hall - - stadium - - tanning_salon - - trampoline_park - - wildlife_hide - - phone - - contact:phone - - email - - contact:email - - website - - contact:website - - capacity:persons - - brand - - abandoned - - yes - - branch - - brand:wikidata - - brand:wikipedia - - takeaway - - - payment:cash - - payment:coins - - payment:notes - - payment:cheque - - payment:electronic_purses - - payment:cards - - payment:debit_cards - - payment:credit_cards - - payment:contactless - - payment:electronic_purses - - payment:stored_value_card - - payment:ep_avant - - payment:ep_beep - - payment:ep_brizzi - - payment:ep_bsbcash - - payment:ep_cash - - payment:ep_flazz - - payment:ep_geldkarte - - payment:ep_mach - - payment:ep_mandiri_emoney - - payment:ep_megacash - - payment:ep_mep - - payment:ep_minicash - - payment:ep_minipay - - payment:ep_monedero - - payment:ep_monedero4b - - payment:ep_nobu_emoney - - payment:ep_stwm_legic - - payment:ep_tapcash - - payment:octopus - - payment:mercado_pago - - payment:debit_cards - - payment:bancomat - - payment:bancontact - - payment:bankaxept - - payment:bankaxess - - payment:cb - - payment:coinkite - - payment:cuentarut - - payment:eps - - payment:girocardpayment:girocard_contactless - - payment:gpn_debit - - payment:interac - - payment:laser - - payment:maestro - - payment:mastercard_debit - - payment:mir - - payment:multibanco - - payment:postfinance_card - - payment:unionpay_debit - - payment:v_pay - - payment:visa_debit - - payment:visa_electron - - payment:credit_cards - - payment:american_express - - payment:bca_card - - payment:dinacard - - payment:diners_club - - payment:discover_card - - payment:jcb - - payment:mastercard - - payment:unionpay - - payment:visa - - payment:contactless - - payment:mastercard_contactlesspayment:paypasspayment:mastercard_paypass - - payment:visa_contactlesspayment:visa_paywavepayment:paywave - - payment:american_express_contactlesspayment:expresspay - - payment:girocard_contactless - - payment:interac_contactless - - payment:maestro_contactless - - payment:quickpass - - payment:rupay_contactless - - payment:berlio - - payment:cfn - - payment:circlek - - payment:dci - - payment:dkv - - payment:esso_card - - payment:eurowag - - payment:hoyer_card - - payment:ids - - payment:omv_card - - payment:petrochina - - payment:roadrunner - - payment:routex - - payment:sinopec - - payment:shell - - payment:snnp - - payment:svg - - payment:total_card - - payment:uta - - payment:sms - - payment:phonepayment:toll_number - - payment:app - - payment:mobile_phone - - payment:telephone_cards - - payment:calling_cards - - payment:reverse_charge_calls - - payment:my_pertamina_app - - payment:parkee_app - - payment:payback_app - - payment:payconiq_app - - payment:payme - - payment:spb - - payment:bob - - payment:china_t-union - - payment:clipper - - payment:ic - - payment:icsf - - payment:ep_ipass - - payment:easycardpayment:ep_easycard - - payment:jak_lingko - - payment:ov-chipkaart - - payment:oyster - - payment:prepaid_ticket - - payment:presto - - payment:sube - - payment:license_plate - - payment:touchngo - - payment:touchngo_smarttag - - payment:touchngo_rfid - - payment:autosweep_rfid - - payment:easytrip - - payment:e_pass - - payment:e_zpass - - payment:fastrak - - payment:k-tag - - payment:good_to_go - - payment:i-pass - - payment:nc_quick_pass - - payment:peach_pass - - payment:pikepass - - payment:sunpass - - payment:via_verde - - payment:cryptocurrencies - - payment:bitcoin - - payment:lightning - - payment:lightning_contactless - - payment:bitcoincash - - payment:litecoin - - payment:dogecoin - - payment:ethereum - - payment:dash - - payment:akulaku - - payment:alipay - - payment:apple_pay - - payment:au_pay - - payment:bcapayment:bca:gpn_qris=yespayment:sakuku - - payment:blik - - payment:bluepaypayment:bluepay:gpn_qris=yes - - payment:cashbac - - payment:d_barai - - payment:danapayment:dana:gpn_qris=yes - - payment:e-cny - - payment:edy - - payment:gcash - - payment:google_paypayment:android_pay - - payment:gopay_idpayment:id_gopay:gpn_qris=yes - - payment:gopay_my - - payment:gpn_qris - - payment:grabpay - - payment:huawei_pay - - payment:id - - payment:isakupayment:isaku:gpn_qris - - payment:kaspro - - payment:line_pay - - payment:jko_pay - - payment:linkaja - - payment:maya - - payment:mbway - - payment:merpay - - payment:mipay - - payment:nanaco - - payment:oplati - - payment:ovo - - payment:paypay - - payment:quicpay - - payment:rakuten_pay - - payment:samsung_pay - - payment:satispay - - payment:sgqr - - payment:shopeepaypayment:shopeepay:gpn_qris - - payment:swish - - payment:touchngo - - payment:twint - - payment:venmo - - payment:vipps - - payment:waon - - payment:wechat - - payment:yukkpayment:yukk:gpn_qris - - payment:zip - - payment:ebt - - payment:snap - - payment:wic - - payment:wire_transfer - - payment:bank_transfer - - payment:invoice - - payment:paypal - - payment:service_voucher - - payment:meal_voucher - - payment:token - - payment:token_coin - - payment:gift_card - - payment:account_cards - - payment:szep - - payment:posta_paletta - - payment:edenred_card - - payment:edenred_voucher - - payment:otp_cafeteria - - payment:multipay - - payment:museumkaart - - payment:u-key - - payment:none - - safety:mask:covid19: - - yes - - no - - given - - sold - - note - - healthcare - - clinic - - hospital - - dentist - - doctor - - pharmacy - - source - - destroyed:building - - yes diff --git a/python/dbapi/api/raw.py b/python/dbapi/api/raw.py index 6c207d8f..9a80539a 100644 --- a/python/dbapi/api/raw.py +++ b/python/dbapi/api/raw.py @@ -116,7 +116,6 @@ def listFeaturesQuery( "AND status = '{0}'".format(status) if (status) else "", "ORDER BY " + orderBy + " DESC LIMIT " + str(RESULTS_PER_PAGE_LIST) + (" OFFSET {0}".format(page * RESULTS_PER_PAGE_LIST) if page else ""), ) - print("status", status) return query class Raw: diff --git a/setup/underpass.sql b/setup/underpass.sql index 145f21c2..33be7d98 100644 --- a/setup/underpass.sql +++ b/setup/underpass.sql @@ -42,7 +42,7 @@ ALTER TABLE ONLY public.changesets DROP TYPE IF EXISTS public.objtype; CREATE TYPE public.objtype AS ENUM ('node', 'way', 'relation'); DROP TYPE IF EXISTS public.status; -CREATE TYPE public.status AS ENUM ('notags', 'complete', 'incomplete', 'badvalue', 'correct', 'badgeom', 'orphan', 'overlaping', 'duplicate'); +CREATE TYPE public.status AS ENUM ('notags', 'complete', 'incomplete', 'badvalue', 'correct', 'badgeom', 'orphan', 'overlapping', 'duplicate'); CREATE TABLE IF NOT EXISTS public.validation ( osm_id int8, diff --git a/src/bootstrap/bootstrap.cc b/src/bootstrap/bootstrap.cc index 0b8699df..05a7b059 100644 --- a/src/bootstrap/bootstrap.cc +++ b/src/bootstrap/bootstrap.cc @@ -75,7 +75,7 @@ void startProcessingWays(const underpassconfig::UnderpassConfig &config) { }; for (auto table_it = tables.begin(); table_it != tables.end(); ++table_it) { - std::cout << "Counting geometries ... " << std::endl; + std::cout << std::endl << "Counting geometries ... " << std::endl; int total = queryraw->getWaysCount(*table_it); std::cout << "Total: " << total << std::endl; if (total > 0) { diff --git a/src/raw/queryraw.cc b/src/raw/queryraw.cc index bd156173..16078244 100644 --- a/src/raw/queryraw.cc +++ b/src/raw/queryraw.cc @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include "utils/log.hh" @@ -369,21 +371,24 @@ QueryRaw::getNodeCacheFromWays(std::shared_ptr> ways, std::m } std::map parseTagsString(std::string input) { - input.pop_back(); - std::map result; - std::stringstream ss(input); - std::string token; - while (std::getline(ss, token, ',')) { - size_t arrowPos = token.find_last_of(":"); - if (arrowPos != std::string::npos) { - std::string key = token.substr(1, arrowPos - 1); - std::string value = token.substr(arrowPos + 2); - key.erase(std::remove( key.begin(), key.end(), '\"' ),key.end()); - value.erase(std::remove( value.begin(), value.end(), '\"' ),value.end()); - result[key] = value; - } + // std::cout << "[INPUT] " << input << std::endl; + std::map tags; + boost::property_tree::ptree pt; + try { + std::istringstream jsonStream(input); + boost::property_tree::read_json(jsonStream, pt); + } catch (const boost::property_tree::json_parser::json_parser_error& e) { + std::cerr << "Error parsing JSON: " << e.what() << std::endl; + return tags; + } + for (const auto& pair : pt) { + tags[pair.first] = pair.second.get_value(); } - return result; + // for (const auto& pair : tags) { + // std::cout << pair.first << "=" << pair.second << std::endl; + // } + // std::cout << std::endl; + return tags; } std::list> diff --git a/src/replicator/threads.cc b/src/replicator/threads.cc index f756caeb..0686f70a 100644 --- a/src/replicator/threads.cc +++ b/src/replicator/threads.cc @@ -535,8 +535,8 @@ threadOsmChange(OsmChangeTask osmChangeTask) for (auto status_it = it->get()->status.begin(); status_it != it->get()->status.end(); ++status_it) { task.query += queryvalidate->applyChange(*it->get(), *status_it); } - if (!it->get()->hasStatus(overlaping)) { - task.query += queryvalidate->updateValidation(it->get()->osm_id, overlaping, "building"); + if (!it->get()->hasStatus(overlapping)) { + task.query += queryvalidate->updateValidation(it->get()->osm_id, overlapping, "building"); } if (!it->get()->hasStatus(duplicate)) { task.query += queryvalidate->updateValidation(it->get()->osm_id, duplicate, "building"); diff --git a/src/testsuite/libunderpass.all/stats-test.cc b/src/testsuite/libunderpass.all/stats-test.cc index b119670c..d9caf1c8 100644 --- a/src/testsuite/libunderpass.all/stats-test.cc +++ b/src/testsuite/libunderpass.all/stats-test.cc @@ -237,7 +237,6 @@ class TestStats { if (this->verbose) { std::cout << "changeset: " << changestats->changeset << std::endl; } - // TODO: get values to test from YAML validation file testStat(changestats, validation, "highway"); testStat(changestats, validation, "building"); testStat(changestats, validation, "humanitarian_building"); diff --git a/src/testsuite/libunderpass.all/test-playground.cc b/src/testsuite/libunderpass.all/test-playground.cc index 8522f893..15f51951 100644 --- a/src/testsuite/libunderpass.all/test-playground.cc +++ b/src/testsuite/libunderpass.all/test-playground.cc @@ -18,44 +18,11 @@ // #include -#include -#include - -std::map parseTagsString(const std::string& input) { - std::map result; - std::stringstream ss(input); - std::string token; - - while (std::getline(ss, token, ',')) { - // std::cout << token << std::endl; - // Remove leading and trailing whitespaces - // token.erase(token.find_first_not_of(" "), token.find_last_not_of(" ") + 1); - // std::cout << token << std::endl; - // Find the position of the arrow - size_t arrowPos = token.find("=>"); - if (arrowPos != std::string::npos) { - std::string key = token.substr(0, arrowPos); - std::string value = token.substr(arrowPos + 2); - result[key] = value; - } - } - - return result; -} int main() { - std::string input = "\"fee\"=>\"no\", \"access\"=>\"yes\""; - std::map resultMap = parseTagsString(input); - - // Iterate over the map and print the key-value pairs - for (const auto& pair : resultMap) { - std::cout << pair.first << ": " << pair.second << std::endl; - } - return 0; } - // local Variables: // mode: C++ // indent-tabs-mode: nil diff --git a/src/testsuite/libunderpass.all/val-test.cc b/src/testsuite/libunderpass.all/val-test.cc index 0b0dfc9b..e6300f7d 100644 --- a/src/testsuite/libunderpass.all/val-test.cc +++ b/src/testsuite/libunderpass.all/val-test.cc @@ -91,6 +91,7 @@ osmobjects::OsmWay readOsmWayFromFile(std::string filename) { } else { log_debug("Couldn't load ! %1%", filespec); }; + osmchange.buildGeometriesFromNodeCache(); return *osmchange.changes.front().get()->ways.front().get(); } @@ -195,7 +196,7 @@ test_semantic(std::shared_ptr &plugin) { // But it's complete status = plugin->checkNode(node, "building"); - if (status->hasStatus(complete)) { + if (!status->hasStatus(incomplete)) { runtest.pass("Validate::checkNode(complete) [semantic building]"); } else { runtest.fail("Validate::checkNode(complete) [semantic building]"); @@ -243,7 +244,7 @@ test_semantic(std::shared_ptr &plugin) { // But it's complete way.addTag("building:material", "sponge"); status = plugin->checkWay(way, "building"); - if (status->hasStatus(complete)) { + if (!status->hasStatus(incomplete)) { runtest.pass("Validate::checkWay(bad value) [semantic building]"); } else { runtest.fail("Validate::checkWay(bad value) [semantic building]"); @@ -418,29 +419,30 @@ test_geospatial(std::shared_ptr &plugin) // } // Overlapping, duplicate - osmchange::OsmChangeFile osmfoverlaping; + osmchange::OsmChangeFile osmfoverlapping; const multipolygon_t poly; filespec = DATADIR; filespec += "/testdata/validation/rect-overlap-and-duplicate-building.osc"; if (boost::filesystem::exists(filespec)) { - osmfoverlaping.readChanges(filespec); + osmfoverlapping.readChanges(filespec); + osmfoverlapping.buildGeometriesFromNodeCache(); } else { log_debug("Couldn't load ! %1%", filespec); } - for (auto it = std::begin(osmfoverlaping.changes); it != std::end(osmfoverlaping.changes); ++it) { + for (auto it = std::begin(osmfoverlapping.changes); it != std::end(osmfoverlapping.changes); ++it) { osmchange::OsmChange *change = it->get(); for (auto nit = std::begin(change->ways); nit != std::end(change->ways); ++nit) { osmobjects::OsmWay *way = nit->get(); way->priority = true; } } - auto wayval = osmfoverlaping.validateWays(poly, plugin); + auto wayval = osmfoverlapping.validateWays(poly, plugin); for (auto sit = wayval->begin(); sit != wayval->end(); ++sit) { auto status = *sit->get(); - if (status.hasStatus(overlaping)) { - runtest.pass("Validate::validateWays(overlaping) [geometry building]"); + if (status.hasStatus(overlapping)) { + runtest.pass("Validate::validateWays(overlapping) [geometry building]"); } else { - runtest.fail("Validate::validateWays(overlaping) [geometry building]"); + runtest.fail("Validate::validateWays(overlapping) [geometry building]"); } if (status.hasStatus(duplicate)) { runtest.pass("Validate::validateWays(duplicate) [geometry building]"); @@ -450,28 +452,28 @@ test_geospatial(std::shared_ptr &plugin) } // No overlapping, no duplicate - osmchange::OsmChangeFile osmfnooverlaping; + osmchange::OsmChangeFile osmfnooverlapping; filespec = DATADIR; filespec += "/testsuite/testdata/validation/rect-no-overlap-and-duplicate-building.osc"; if (boost::filesystem::exists(filespec)) { - osmfnooverlaping.readChanges(filespec); + osmfnooverlapping.readChanges(filespec); } else { log_debug("Couldn't load ! %1%", filespec); } - for (auto it = std::begin(osmfnooverlaping.changes); it != std::end(osmfnooverlaping.changes); ++it) { + for (auto it = std::begin(osmfnooverlapping.changes); it != std::end(osmfnooverlapping.changes); ++it) { osmchange::OsmChange *change = it->get(); for (auto nit = std::begin(change->ways); nit != std::end(change->ways); ++nit) { osmobjects::OsmWay *way = nit->get(); way->priority = true; } } - wayval = osmfnooverlaping.validateWays(poly, plugin); + wayval = osmfnooverlapping.validateWays(poly, plugin); for (auto sit = wayval->begin(); sit != wayval->end(); ++sit) { auto status = *sit->get(); - if (!status.hasStatus(overlaping)) { - runtest.pass("Validate::validateWays(no overlaping) [geometry building]"); + if (!status.hasStatus(overlapping)) { + runtest.pass("Validate::validateWays(no overlapping) [geometry building]"); } else { - runtest.fail("Validate::validateWays(no overlaping) [geometry building]"); + runtest.fail("Validate::validateWays(no overlapping) [geometry building]"); } if (!status.hasStatus(duplicate)) { runtest.pass("Validate::validateWays(no duplicate) [geometry building]"); diff --git a/src/testsuite/testdata/validation/config/building.yaml b/src/testsuite/testdata/validation/config/building.yaml index 519b6f9f..b63b58ee 100644 --- a/src/testsuite/testdata/validation/config/building.yaml +++ b/src/testsuite/testdata/validation/config/building.yaml @@ -1,16 +1,12 @@ config: - - minangle: - - 70 - - maxangle: - - 110 - - anglethreshold: - - 19 - - overlaps: + - badgeom: - yes - - duplicate: - - yes - - enable_tag_values: + - badgeom_minangle: + - 89 + - badgeom_maxangle: + - 91 + - badvalue: - yes tags: diff --git a/src/validate/defaultvalidation.cc b/src/validate/defaultvalidation.cc index 8655ee31..5a95502c 100644 --- a/src/validate/defaultvalidation.cc +++ b/src/validate/defaultvalidation.cc @@ -70,7 +70,9 @@ DefaultValidation::checkWay(const osmobjects::OsmWay &way, const std::string &ty yaml::Yaml tests = yamls[type]; semantic::Semantic::checkWay(way, type, tests, status); geospatial::Geospatial::checkWay(way, type, tests, status); - boost::geometry::centroid(way.linestring, status->center); + if (way.linestring.size() > 2) { + boost::geometry::centroid(way.linestring, status->center); + } status->source = type; return status; } diff --git a/src/validate/geospatial.cc b/src/validate/geospatial.cc index 79bbbaf2..3ee110fe 100644 --- a/src/validate/geospatial.cc +++ b/src/validate/geospatial.cc @@ -51,37 +51,44 @@ Geospatial::Geospatial() {} std::shared_ptr Geospatial::checkWay(const osmobjects::OsmWay &way, const std::string &type, yaml::Yaml &tests, std::shared_ptr &status) { - // On non-english numeric locales using decimal separator different than '.' - // this is necessary to parse double strings with std::stod correctly - // without loosing precision - // std::setlocale(LC_NUMERIC, "C"); - setlocale(LC_NUMERIC, "C"); - if (way.action == osmobjects::remove) { return status; } - // These values are in the config section of the YAML file auto config = tests.get("config"); + bool check_badgeom = config.get_value("badgeom") == "yes"; + // bool check_overlapping = config.get_value("overlapping") == "yes"; + // bool check_duplicate = config.get_value("duplicate") == "yes"; + + if (check_badgeom) { + auto badgeom_minangle = config.get_value("badgeom_minangle"); + auto badgeom_maxangle = config.get_value("badgeom_maxangle"); + if (badgeom_minangle != "" && badgeom_maxangle != "") { + if (unsquared(way.linestring, std::stod(badgeom_minangle), std::stod(badgeom_maxangle))) { + status->status.insert(badgeom); + } + } else { + if (unsquared(way.linestring)) { + status->status.insert(badgeom); + } + } - // if (config.contains_value("overlaps", "yes")) { + } + + // if (check_overlapping) { // auto allWays = context.getOverlappingWays(); // if (overlaps(allWays, way)) { - // status->status.insert(overlaping); + // status->status.insert(overlapping); // } // } - // if (config.contains_value("duplicate", "yes")) { + // if (check_duplicate) { // auto allWays = context.getOverlappingWays(); // if (overlaps(allWays, way)) { - // status->status.insert(overlaping); + // status->status.insert(overlapping); // } // } - if (unsquared(way.linestring)) { - status->status.insert(badgeom); - } - return status; } @@ -107,8 +114,6 @@ Geospatial::overlaps(const std::list> &allwa bool Geospatial::duplicate(const std::list> &allways, osmobjects::OsmWay &way) { - // This test only applies to buildings, as highways often overlap. - // TODO: move logic to a config file #ifdef TIMING_DEBUG_X boost::timer::auto_cpu_timer timer("validate::duplicate: took %w seconds\n"); #endif diff --git a/src/validate/queryvalidate.cc b/src/validate/queryvalidate.cc index dcbe8933..499beae6 100644 --- a/src/validate/queryvalidate.cc +++ b/src/validate/queryvalidate.cc @@ -69,7 +69,7 @@ std::map status_list = { {badvalue, "badvalue"}, {correct, "correct"}, {orphan, "orphan"}, - {overlaping, "overlaping"}, + {overlapping, "overlapping"}, {duplicate, "duplicate"}, {badgeom, "badgeom"} }; diff --git a/src/validate/semantic.cc b/src/validate/semantic.cc index 1c06af4f..8f9feb94 100644 --- a/src/validate/semantic.cc +++ b/src/validate/semantic.cc @@ -66,21 +66,25 @@ Semantic::checkTag(const std::string &key, const std::string &value, std::shared if (!key.empty() && value.empty()) { log_debug("WARNING: empty value for tag \"%1%\"", key); status->status.insert(badvalue); + status->values.insert(key + "=" + value); } // Check for a space in the tag key if (key.find(' ') != std::string::npos) { log_error("WARNING: spaces in tag key \"%1%\"", key); status->status.insert(badvalue); + status->values.insert(key + "=" + value); } // Check for single quotes in the tag value - if (value.find('\'') != std::string::npos) { - log_error("WARNING: single quote in tag value \"%1%\"", value); + if (key.find('\'') != std::string::npos) { + log_error("WARNING: single quote in tag key \"%1%\"", value); status->status.insert(badvalue); + status->values.insert(key + "=" + value); } - // Check for single quotes in the tag value - if (value.find('\"') != std::string::npos) { - log_error("WARNING: double quote in tag value \"%1%\"", value); + // Check for double quotes in the tag key + if (key.find('\"') != std::string::npos) { + log_error("WARNING: double quote in tag key \"%1%\"", value); status->status.insert(badvalue); + status->values.insert(key + "=" + value); } } @@ -147,48 +151,49 @@ Semantic::checkNode(const osmobjects::OsmNode &node, const std::string &type, ya std::shared_ptr Semantic::checkWay(const osmobjects::OsmWay &way, const std::string &type, yaml::Yaml &tests, std::shared_ptr &status) { - // On non-english numeric locales using decimal separator different than '.' - // this is necessary to parse double strings with std::stod correctly - // without loosing precision - // std::setlocale(LC_NUMERIC, "C"); - setlocale(LC_NUMERIC, "C"); - - if (way.tags.size() == 0) { - status->status.insert(notags); - return status; - } if (way.action == osmobjects::remove) { return status; } - std::string key; - // List of valid tags to be validated - auto tags = tests.get("tags"); - // These values are in the config section of the YAML file auto config = tests.get("config"); + bool check_badvalue = config.get_value("badvalue") == "yes"; + bool check_incomplete = config.get_value("incomplete") == "yes"; - // Not using required_tags disables writing features flagged for not being tag complete - // from being written to the database thus reducing the size of the results. - auto required_tags = tests.get("required_tags"); + // List of required tags to be validated + yaml::Node required_tags; + if (check_incomplete) { + required_tags = tests.get("required_tags"); + } - // This enables/disables writing features flagged for not having values - // in range as defined in the YAML config file. This prevents those - // from being written to the database to reduce the size of the results. + // List of valid tags to be validated + yaml::Node tags; + if (check_badvalue) { + tags = tests.get("tags"); + } + + if (check_badvalue && way.tags.size() == 0) { + status->status.insert(notags); + return status; + } int tagexists = 0; for (auto vit = std::begin(way.tags); vit != std::end(way.tags); ++vit) { - if (!isValidTag(vit->first, vit->second, tags)) { - status->status.insert(badvalue); - status->values.insert(vit->first + "=" + vit->second); + if (check_badvalue) { + if (tags.children.size() > 0 && !isValidTag(vit->first, vit->second, tags)) { + status->status.insert(badvalue); + status->values.insert(vit->first + "=" + vit->second); + } + checkTag(vit->first, vit->second, status); } - if (isRequiredTag(vit->first, required_tags)) { - tagexists++; + if (check_incomplete) { + if (isRequiredTag(vit->first, required_tags)) { + tagexists++; + } } - // checkTag(vit->first, vit->second, status); } - if (tagexists != required_tags.children.size()) { + if (check_incomplete && tagexists != required_tags.children.size()) { status->status.insert(incomplete); } diff --git a/src/validate/validate.hh b/src/validate/validate.hh index 6f96b674..a03439e0 100644 --- a/src/validate/validate.hh +++ b/src/validate/validate.hh @@ -88,7 +88,7 @@ typedef enum { correct, badgeom, orphan, - overlaping, + overlapping, duplicate, valid } valerror_t; @@ -141,7 +141,7 @@ class ValidateStatus { results[correct] = "Correct tag value"; results[badgeom] = "Bad geometry"; results[orphan] = "Orphan"; - results[overlaping] = "Overlap"; + results[overlapping] = "Overlap"; results[duplicate] = "Duplicate"; for (const auto &stat: std::as_const(status)) { std::cerr << "\tResult: " << results[stat] << std::endl; @@ -183,7 +183,6 @@ class BOOST_SYMBOL_VISIBLE Validate { for (auto &file: std::filesystem::recursive_directory_iterator(path)) { std::filesystem::path config = file.path(); if (config.extension() == ".yaml") { - std::cout << "Loading: " << config.stem() << std::endl; yaml::Yaml yaml; yaml.read(config.string()); if (!config.stem().empty()) { diff --git a/src/wrappers/python.cc b/src/wrappers/python.cc index c3b0efbb..7bc666d3 100644 --- a/src/wrappers/python.cc +++ b/src/wrappers/python.cc @@ -47,7 +47,7 @@ std::map results = { {correct, "correct"}, {badgeom, "badgeom"}, {orphan, "orphan"}, - {overlaping, "overlaping"}, + {overlapping, "overlapping"}, {duplicate, "duplicate"} };