@@ -24,6 +24,7 @@ namespace {
2424const std::size_t MinPointsSize = 100 ;
2525const std::size_t MinLinePointsSize = 50 ;
2626const double InvalidDistance = std::numeric_limits<double >::quiet_NaN();
27+ const mapbox::cheap_ruler::CheapRuler::Unit UnitInMeters = mapbox::cheap_ruler::CheapRuler::Unit::Meters;
2728
2829// Inclusive index range for multipoint or linestring container
2930using IndexRange = std::pair<std::size_t , std::size_t >;
@@ -327,9 +328,8 @@ double lineToLinesDistance(const mapbox::geometry::line_string<double>& line,
327328}
328329
329330double pointsToGeometryDistance (const mapbox::geometry::multi_point<double >& points,
330- const Feature::geometry_type& geoSet,
331- mapbox::cheap_ruler::CheapRuler::Unit unit) {
332- mapbox::cheap_ruler::CheapRuler ruler (points.front ().y , unit);
331+ const Feature::geometry_type& geoSet) {
332+ mapbox::cheap_ruler::CheapRuler ruler (points.front ().y , UnitInMeters);
333333 return geoSet.match (
334334 [&points, &ruler](const mapbox::geometry::point<double >& p) {
335335 return pointsToPointsDistance (mapbox::geometry::multi_point<double >{p}, points, ruler);
@@ -346,11 +346,9 @@ double pointsToGeometryDistance(const mapbox::geometry::multi_point<double>& poi
346346 [](const auto &) { return InvalidDistance; });
347347}
348348
349- double lineToGeometryDistance (const mapbox::geometry::line_string<double >& line,
350- const Feature::geometry_type& geoSet,
351- mapbox::cheap_ruler::CheapRuler::Unit unit) {
349+ double lineToGeometryDistance (const mapbox::geometry::line_string<double >& line, const Feature::geometry_type& geoSet) {
352350 assert (!line.empty ());
353- mapbox::cheap_ruler::CheapRuler ruler (line.front ().y , unit );
351+ mapbox::cheap_ruler::CheapRuler ruler (line.front ().y , UnitInMeters );
354352 return geoSet.match (
355353 [&line, &ruler](const mapbox::geometry::point<double >& p) {
356354 return pointsToLineDistance (mapbox::geometry::multi_point<double >{p}, line, ruler);
@@ -369,23 +367,22 @@ double lineToGeometryDistance(const mapbox::geometry::line_string<double>& line,
369367
370368double calculateDistance (const GeometryTileFeature& feature,
371369 const CanonicalTileID& canonical,
372- const Feature::geometry_type& geoSet,
373- mapbox::cheap_ruler::CheapRuler::Unit unit) {
370+ const Feature::geometry_type& geoSet) {
374371 return convertGeometry (feature, canonical)
375372 .match (
376- [&geoSet, &unit ](const mapbox::geometry::point<double >& point) -> double {
377- return pointsToGeometryDistance (mapbox::geometry::multi_point<double >{point}, geoSet, unit );
373+ [&geoSet](const mapbox::geometry::point<double >& point) -> double {
374+ return pointsToGeometryDistance (mapbox::geometry::multi_point<double >{point}, geoSet);
378375 },
379- [&geoSet, &unit ](const mapbox::geometry::multi_point<double >& points) -> double {
380- return pointsToGeometryDistance (points, geoSet, unit );
376+ [&geoSet](const mapbox::geometry::multi_point<double >& points) -> double {
377+ return pointsToGeometryDistance (points, geoSet);
381378 },
382- [&geoSet, &unit ](const mapbox::geometry::line_string<double >& line) -> double {
383- return lineToGeometryDistance (line, geoSet, unit );
379+ [&geoSet](const mapbox::geometry::line_string<double >& line) -> double {
380+ return lineToGeometryDistance (line, geoSet);
384381 },
385- [&geoSet, &unit ](const mapbox::geometry::multi_line_string<double >& lines) -> double {
382+ [&geoSet](const mapbox::geometry::multi_line_string<double >& lines) -> double {
386383 double dist = std::numeric_limits<double >::infinity ();
387384 for (const auto & line : lines) {
388- auto tempDist = lineToGeometryDistance (line, geoSet, unit );
385+ auto tempDist = lineToGeometryDistance (line, geoSet);
389386 if (std::isnan (tempDist)) return tempDist;
390387 dist = std::min (dist, tempDist);
391388 if (dist == 0.0 || std::isnan (dist)) return dist;
@@ -395,15 +392,7 @@ double calculateDistance(const GeometryTileFeature& feature,
395392 [](const auto &) -> double { return InvalidDistance; });
396393}
397394
398- struct Arguments {
399- Arguments (GeoJSON& geojson_, mapbox::cheap_ruler::CheapRuler::Unit unit_)
400- : geojson(std::move(geojson_)), unit(unit_) {}
401-
402- GeoJSON geojson;
403- mapbox::cheap_ruler::CheapRuler::Unit unit;
404- };
405-
406- optional<Arguments> parseValue (const style::conversion::Convertible& value, style::expression::ParsingContext& ctx) {
395+ optional<GeoJSON> parseValue (const style::conversion::Convertible& value, style::expression::ParsingContext& ctx) {
407396 if (isArray (value)) {
408397 // object value, quoted with ["Distance", GeoJSONObj, "unit(optional)"]
409398 auto length = arrayLength (value);
@@ -413,42 +402,13 @@ optional<Arguments> parseValue(const style::conversion::Convertible& value, styl
413402 return nullopt ;
414403 }
415404
416- // Parse Unit info for distance calculation, "Meters" by default
417- mapbox::cheap_ruler::CheapRuler::Unit unit = mapbox::cheap_ruler::CheapRuler::Unit::Meters;
418- if (length == 3 ) {
419- auto input = toString (arrayMember (value, 2 ));
420- if (input == nullopt ) {
421- ctx.error (" Failed to parse unit argument from 'distance' expression" );
422- return nullopt ;
423- }
424- if (*input == " meters" || *input == " metres" ) {
425- unit = mapbox::cheap_ruler::CheapRuler::Unit::Meters;
426- } else if (*input == " kilometers" ) {
427- unit = mapbox::cheap_ruler::CheapRuler::Unit::Kilometers;
428- } else if (*input == " miles" ) {
429- unit = mapbox::cheap_ruler::CheapRuler::Unit::Miles;
430- } else if (*input == " nauticalmiles" ) {
431- unit = mapbox::cheap_ruler::CheapRuler::Unit::NauticalMiles;
432- } else if (*input == " yards" ) {
433- unit = mapbox::cheap_ruler::CheapRuler::Unit::Yards;
434- } else if (*input == " feet" ) {
435- unit = mapbox::cheap_ruler::CheapRuler::Unit::Feet;
436- } else if (*input == " inches" ) {
437- unit = mapbox::cheap_ruler::CheapRuler::Unit::Inches;
438- } else {
439- ctx.error (
440- " 'distance' expression only accepts following units: kilometers, miles, nauticalmiles, "
441- " meters, metres, yards, feet, inches." );
442- return nullopt ;
443- }
444- }
445405 // Parse geometry info
446406 const auto & argument1 = arrayMember (value, 1 );
447407 if (isObject (argument1)) {
448408 style::conversion::Error error;
449409 auto geojson = toGeoJSON (argument1, error);
450410 if (geojson && error.message .empty ()) {
451- return Arguments ( *geojson, unit) ;
411+ return *geojson;
452412 }
453413 ctx.error (error.message );
454414 }
@@ -472,11 +432,8 @@ optional<Feature::geometry_type> getGeometry(const Feature& feature, mbgl::style
472432namespace style {
473433namespace expression {
474434
475- Distance::Distance (GeoJSON geojson, Feature::geometry_type geometries_, mapbox::cheap_ruler::CheapRuler::Unit unit_)
476- : Expression(Kind::Distance, type::Number),
477- geoJSONSource (std::move(geojson)),
478- geometries(std::move(geometries_)),
479- unit(unit_) {}
435+ Distance::Distance (GeoJSON geojson, Feature::geometry_type geometries_)
436+ : Expression(Kind::Distance, type::Number), geoJSONSource(std::move(geojson)), geometries(std::move(geometries_)) {}
480437
481438Distance::~Distance () = default ;
482439
@@ -488,7 +445,7 @@ EvaluationResult Distance::evaluate(const EvaluationContext& params) const {
488445 }
489446 auto geometryType = params.feature ->getType ();
490447 if (geometryType == FeatureType::Point || geometryType == FeatureType::LineString) {
491- auto distance = calculateDistance (*params.feature , *params.canonical , geometries, unit );
448+ auto distance = calculateDistance (*params.feature , *params.canonical , geometries);
492449 if (!std::isnan (distance)) {
493450 assert (distance >= 0.0 );
494451 return distance;
@@ -503,26 +460,23 @@ ParseResult Distance::parse(const Convertible& value, ParsingContext& ctx) {
503460 return ParseResult ();
504461 }
505462
506- return parsedValue->geojson . match (
463+ return parsedValue->match (
507464 [&parsedValue, &ctx](const mapbox::geometry::geometry<double >& geometrySet) {
508465 if (auto ret = getGeometry (mbgl::Feature (geometrySet), ctx)) {
509- return ParseResult (
510- std::make_unique<Distance>(parsedValue->geojson , std::move (*ret), parsedValue->unit ));
466+ return ParseResult (std::make_unique<Distance>(*parsedValue, std::move (*ret)));
511467 }
512468 return ParseResult ();
513469 },
514470 [&parsedValue, &ctx](const mapbox::feature::feature<double >& feature) {
515471 if (auto ret = getGeometry (mbgl::Feature (feature), ctx)) {
516- return ParseResult (
517- std::make_unique<Distance>(parsedValue->geojson , std::move (*ret), parsedValue->unit ));
472+ return ParseResult (std::make_unique<Distance>(*parsedValue, std::move (*ret)));
518473 }
519474 return ParseResult ();
520475 },
521476 [&parsedValue, &ctx](const mapbox::feature::feature_collection<double >& features) {
522477 for (const auto & feature : features) {
523478 if (auto ret = getGeometry (mbgl::Feature (feature), ctx)) {
524- return ParseResult (
525- std::make_unique<Distance>(parsedValue->geojson , std::move (*ret), parsedValue->unit ));
479+ return ParseResult (std::make_unique<Distance>(*parsedValue, std::move (*ret)));
526480 }
527481 }
528482 return ParseResult ();
@@ -566,27 +520,6 @@ mbgl::Value convertValue(const mapbox::geojson::rapidjson_value& v) {
566520 return Null;
567521}
568522
569- std::string getUnits (const mapbox::cheap_ruler::CheapRuler::Unit& unit) {
570- switch (unit) {
571- case mapbox::cheap_ruler::CheapRuler::Kilometers:
572- return " kilometers" ;
573- case mapbox::cheap_ruler::CheapRuler::Miles:
574- return " miles" ;
575- case mapbox::cheap_ruler::CheapRuler::NauticalMiles:
576- return " nauticalmiles" ;
577- case mapbox::cheap_ruler::CheapRuler::Meters:
578- return " meters" ;
579- case mapbox::cheap_ruler::CheapRuler::Yards:
580- return " yards" ;
581- case mapbox::cheap_ruler::CheapRuler::Feet:
582- return " feet" ;
583- case mapbox::cheap_ruler::CheapRuler::Inches:
584- return " inches" ;
585- default :
586- return " error" ;
587- }
588- }
589-
590523mbgl::Value Distance::serialize () const {
591524 std::unordered_map<std::string, mbgl::Value> serialized;
592525 rapidjson::CrtAllocator allocator;
@@ -599,13 +532,13 @@ mbgl::Value Distance::serialize() const {
599532 mbgl::Log::Error (mbgl::Event::General,
600533 " Failed to serialize 'distance' expression, converted rapidJSON is not an object" );
601534 }
602- return std::vector<mbgl::Value>{{getOperator (), serialized, getUnits (unit) }};
535+ return std::vector<mbgl::Value>{{getOperator (), serialized}};
603536}
604537
605538bool Distance::operator ==(const Expression& e) const {
606539 if (e.getKind () == Kind::Distance) {
607540 auto rhs = static_cast <const Distance*>(&e);
608- return geoJSONSource == rhs->geoJSONSource && geometries == rhs->geometries && unit == rhs-> unit ;
541+ return geoJSONSource == rhs->geoJSONSource && geometries == rhs->geometries ;
609542 }
610543 return false ;
611544}
0 commit comments