From bacf1f59ca8e06b5b5423a35b4e4c30d92624758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Fri, 27 May 2016 13:41:49 -0700 Subject: [PATCH] [ios, osx] Cleaned up evaluators Removed a level of indirection when creating Objective-C collections from C++ collections. Adopted mbgl typedefs for geometry.hpp types. Factored out MGLPolygon construction. --- platform/darwin/src/MGLFeature.mm | 130 ++++++++++++------------------ 1 file changed, 52 insertions(+), 78 deletions(-) diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm index 066d3609a..777b29630 100644 --- a/platform/darwin/src/MGLFeature.mm +++ b/platform/darwin/src/MGLFeature.mm @@ -6,6 +6,8 @@ #import "MGLMultiPoint_Private.h" +#import + @protocol MGLFeaturePrivate @property (nonatomic, copy, nullable, readwrite) id identifier; @@ -141,24 +143,19 @@ public: } id operator()(const std::vector &values) const { - std::vector objects; - objects.reserve(values.size()); + NSMutableArray *objects = [NSMutableArray arrayWithCapacity:values.size()]; for (const auto &v : values) { - objects.push_back(mbgl::Value::visit(v, *this)); + [objects addObject:mbgl::Value::visit(v, *this)]; } - return [NSArray arrayWithObjects:&objects[0] count:objects.size()]; + return objects; } id operator()(const std::unordered_map &items) const { - std::vector keys; - keys.reserve(items.size()); - std::vector objects; - objects.reserve(items.size()); + NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithCapacity:items.size()]; for (auto &item : items) { - keys.push_back(@(item.first.c_str())); - objects.push_back(mbgl::Value::visit(item.second, *this)); + attributes[@(item.first.c_str())] = mbgl::Value::visit(item.second, *this); } - return [NSDictionary dictionaryWithObjects:&objects[0] forKeys:&keys[0] count:keys.size()]; + return attributes; } }; @@ -169,57 +166,30 @@ public: template class GeometryEvaluator { public: - MGLShape * operator()(const mapbox::geometry::point &geometry) const { + MGLShape * operator()(const mbgl::Point &geometry) const { MGLPointFeature *feature = [[MGLPointFeature alloc] init]; - feature.coordinate = coordinateFromPointGeometry(geometry); + feature.coordinate = toLocationCoordinate2D(geometry); return feature; } - MGLShape * operator()(const mapbox::geometry::line_string &geometry) const { - std::vector coordinates; - coordinates.reserve(geometry.size()); - std::transform(geometry.begin(), geometry.end(), std::back_inserter(coordinates), coordinateFromPointGeometry); - + MGLShape * operator()(const mbgl::LineString &geometry) const { + std::vector coordinates = toLocationCoordinates2D(geometry); return [MGLPolylineFeature polylineWithCoordinates:&coordinates[0] count:coordinates.size()]; } - MGLShape * operator()(const mapbox::geometry::polygon &geometry) const { - auto &outerRing = geometry.front(); - std::vector coordinates; - coordinates.reserve(outerRing.size()); - std::transform(outerRing.begin(), outerRing.end(), std::back_inserter(coordinates), coordinateFromPointGeometry); - - NSMutableArray *innerPolygons; - if (geometry.size() > 1) { - innerPolygons = [NSMutableArray arrayWithCapacity:geometry.size() - 1]; - for (auto iter = geometry.begin() + 1; iter != geometry.end(); iter++) { - auto &innerRing = *iter; - std::vector coordinates; - coordinates.reserve(innerRing.size()); - std::transform(innerRing.begin(), innerRing.end(), std::back_inserter(coordinates), coordinateFromPointGeometry); - MGLPolygon *innerPolygon = [MGLPolygon polygonWithCoordinates:&coordinates[0] count:coordinates.size()]; - [innerPolygons addObject:innerPolygon]; - } - } - - return [MGLPolygonFeature polygonWithCoordinates:&coordinates[0] count:coordinates.size() interiorPolygons:innerPolygons]; + MGLShape * operator()(const mbgl::Polygon &geometry) const { + return toShape(geometry); } - MGLShape * operator()(const mapbox::geometry::multi_point &geometry) const { - std::vector coordinates; - coordinates.reserve(geometry.size()); - std::transform(geometry.begin(), geometry.end(), std::back_inserter(coordinates), coordinateFromPointGeometry); - + MGLShape * operator()(const mbgl::MultiPoint &geometry) const { + std::vector coordinates = toLocationCoordinates2D(geometry); return [[MGLMultiPointFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()]; } - MGLShape * operator()(const mapbox::geometry::multi_line_string &geometry) const { + MGLShape * operator()(const mbgl::MultiLineString &geometry) const { NSMutableArray *polylines = [NSMutableArray arrayWithCapacity:geometry.size()]; for (auto &lineString : geometry) { - std::vector coordinates; - coordinates.reserve(lineString.size()); - std::transform(lineString.begin(), lineString.end(), std::back_inserter(coordinates), coordinateFromPointGeometry); - + std::vector coordinates = toLocationCoordinates2D(lineString); MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:&coordinates[0] count:coordinates.size()]; [polylines addObject:polyline]; } @@ -227,29 +197,10 @@ public: return [MGLMultiPolylineFeature multiPolylineWithPolylines:polylines]; } - MGLShape * operator()(const mapbox::geometry::multi_polygon &geometry) const { + MGLShape * operator()(const mbgl::MultiPolygon &geometry) const { NSMutableArray *polygons = [NSMutableArray arrayWithCapacity:geometry.size()]; for (auto &polygon : geometry) { - auto &linearRing = polygon.front(); - std::vector coordinates; - coordinates.reserve(linearRing.size()); - std::transform(linearRing.begin(), linearRing.end(), std::back_inserter(coordinates), coordinateFromPointGeometry); - - NSMutableArray *innerPolygons; - if (polygon.size() > 1) { - innerPolygons = [NSMutableArray arrayWithCapacity:polygon.size() - 1]; - for (auto iter = polygon.begin() + 1; iter != polygon.end(); iter++) { - auto &innerRing = *iter; - std::vector coordinates; - coordinates.reserve(innerRing.size()); - std::transform(innerRing.begin(), innerRing.end(), std::back_inserter(coordinates), coordinateFromPointGeometry); - MGLPolygon *innerPolygon = [MGLPolygon polygonWithCoordinates:&coordinates[0] count:coordinates.size()]; - [innerPolygons addObject:innerPolygon]; - } - } - - MGLPolygon *polygonObject = [MGLPolygon polygonWithCoordinates:&coordinates[0] count:coordinates.size() interiorPolygons:innerPolygons]; - [polygons addObject:polygonObject]; + [polygons addObject:toShape(polygon)]; } return [MGLMultiPolygonFeature multiPolygonWithPolygons:polygons]; @@ -259,23 +210,46 @@ public: NSMutableArray *shapes = [NSMutableArray arrayWithCapacity:collection.size()]; for (auto &geometry : collection) { // This is very much like the transformation that happens in MGLFeaturesFromMBGLFeatures(), but these are raw geometries with no associated feature IDs or attributes. - GeometryEvaluator evaluator; - MGLShape *shape = mapbox::geometry::geometry::visit(geometry, evaluator); + MGLShape *shape = mapbox::geometry::geometry::visit(geometry, *this); [shapes addObject:shape]; } return [MGLShapeCollectionFeature shapeCollectionWithShapes:shapes]; } private: - static CLLocationCoordinate2D coordinateFromPointGeometry(const mapbox::geometry::point &point) { + static CLLocationCoordinate2D toLocationCoordinate2D(const mbgl::Point &point) { return CLLocationCoordinate2DMake(point.y, point.x); } + + static std::vector toLocationCoordinates2D(const std::vector> &points) { + std::vector coordinates; + coordinates.reserve(points.size()); + std::transform(points.begin(), points.end(), std::back_inserter(coordinates), toLocationCoordinate2D); + return coordinates; + } + + template + static U *toShape(const mbgl::Polygon &geometry) { + auto &linearRing = geometry.front(); + std::vector coordinates = toLocationCoordinates2D(linearRing); + NSMutableArray *innerPolygons; + if (geometry.size() > 1) { + innerPolygons = [NSMutableArray arrayWithCapacity:geometry.size() - 1]; + for (auto iter = geometry.begin() + 1; iter != geometry.end(); iter++) { + auto &innerRing = *iter; + std::vector coordinates = toLocationCoordinates2D(innerRing); + MGLPolygon *innerPolygon = [MGLPolygon polygonWithCoordinates:&coordinates[0] count:coordinates.size()]; + [innerPolygons addObject:innerPolygon]; + } + } + + return [U polygonWithCoordinates:&coordinates[0] count:coordinates.size() interiorPolygons:innerPolygons]; + } }; NS_ARRAY_OF(MGLShape *) *MGLFeaturesFromMBGLFeatures(const std::vector &features) { - std::vector *> shapes; - shapes.reserve(features.size()); - std::transform(features.begin(), features.end(), std::back_inserter(shapes), ^MGLShape * (const mbgl::Feature &feature) { + NSMutableArray *shapes = [NSMutableArray arrayWithCapacity:features.size()]; + for (const auto &feature : features) { NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithCapacity:feature.properties.size()]; for (auto &pair : feature.properties) { auto &value = pair.second; @@ -289,7 +263,7 @@ NS_ARRAY_OF(MGLShape *) *MGLFeaturesFromMBGLFeatures(const std::vec shape.identifier = @(*feature.id); } shape.attributes = attributes; - return shape; - }); - return [NSArray arrayWithObjects:&shapes[0] count:shapes.size()]; + [shapes addObject:shape]; + } + return shapes; }