// Expands bounding box using given coordinate. inline void expand(const GeoCoordinate& c) { minPoint = GeoCoordinate( std::min(minPoint.latitude, c.latitude), std::min(minPoint.longitude, c.longitude)); maxPoint = GeoCoordinate( std::max(maxPoint.latitude, c.latitude), std::max(maxPoint.longitude, c.longitude)); }
// Expands bounding box using given coordinate. inline void expand(const GeoCoordinate& c) { minPoint = GeoCoordinate( minPoint.latitude < c.latitude ? minPoint.latitude : c.latitude, minPoint.longitude < c.longitude ? minPoint.longitude : c.longitude); maxPoint = GeoCoordinate( maxPoint.latitude > c.latitude ? maxPoint.latitude : c.latitude, maxPoint.longitude > c.longitude ? maxPoint.longitude : c.longitude); }
// Gets double value or zero. inline double getValue(key_type keyId, double size = 1, const utymap::GeoCoordinate& coordinate = GeoCoordinate()) const { if (!has(keyId)) return 0; auto declaration = get(keyId); auto rawValue = declaration->value(); char dimen = (*rawValue)[rawValue->size() - 1]; // in meters if (dimen == 'm' && coordinate.isValid()) { double value = std::stod(rawValue->substr(0, rawValue->size() - 1)); return utymap::utils::GeoUtils::getOffset(coordinate, value); } // relative to size if (dimen == '%') { double value = std::stod(rawValue->substr(0, rawValue->size() - 1)); return size * value * 0.01; } return declaration->isEval() ? declaration->evaluate<double>(tags_, stringTable_) : std::stod(*rawValue); }
// Gets double value or zero. inline double getValue(const std::string& key, double size = 1, const utymap::GeoCoordinate& coordinate = GeoCoordinate()) const { key_type keyId = stringTable_.getId(key); return getValue(keyId, size, coordinate); }
/// Converts given world coordinate represented by (x, y) to geocoordinate. static GeoCoordinate worldToGeo(const GeoCoordinate &worldZero, double x, double y) { double latitudeCircumference = LatitudeEquator*std::cos(utymap::utils::deg2Rad(worldZero.latitude)); auto deltaLongitude = (x*360)/latitudeCircumference; auto deltaLatitude = (y*360)/CircleDistance; return GeoCoordinate(worldZero.latitude + deltaLatitude, worldZero.longitude + deltaLongitude); }
void build(const Element& element, const Style& style) { MeshContext meshContext(*mesh_, style); auto geoCoordinate = GeoCoordinate(polygon_->points[1], polygon_->points[0]); double height = style.getValue(HeightKey); // NOTE do not allow height to be zero. This might happen due to the issues in input osm data. if (height == 0) height = 10; double minHeight = style.getValue(MinHeightKey); double elevation = context_.eleProvider.getElevation(geoCoordinate) + minHeight; height -= minHeight; // roof auto roofType = style.getString(RoofTypeKey); double roofHeight = style.getValue(RoofHeightKey); auto roofGradient = GradientUtils::evaluateGradient(context_.styleProvider, meshContext.style, element.tags, RoofColorKey); auto roofBuilder = RoofBuilderFactoryMap.find(*roofType)->second(context_, meshContext); roofBuilder->setHeight(roofHeight); roofBuilder->setMinHeight(elevation + height); roofBuilder->setColor(roofGradient, 0); roofBuilder->build(*polygon_); // facade auto facadeType = style.getString(FacadeTypeKey); auto facadeBuilder = FacadeBuilderFactoryMap.find(*facadeType)->second(context_, meshContext); auto facadeGradient = GradientUtils::evaluateGradient(context_.styleProvider, meshContext.style, element.tags, FacadeColorKey); facadeBuilder->setHeight(height); facadeBuilder->setMinHeight(elevation); facadeBuilder->setColor(facadeGradient, 0); facadeBuilder->build(*polygon_); polygon_.reset(); }
// Returns center of bounding box. inline GeoCoordinate center() const { return GeoCoordinate( minPoint.latitude + (maxPoint.latitude - minPoint.latitude) / 2, minPoint.longitude + (maxPoint.longitude - minPoint.longitude) / 2); }
BoundingBox() : BoundingBox(GeoCoordinate(90, 180), GeoCoordinate(-90, -180)) { }
inline void setCoordinates(T& t, const ClipperLib::Path& path) { t.coordinates.reserve(path.size()); for (const auto& c : path) { t.coordinates.push_back(GeoCoordinate(c.Y / Scale, c.X / Scale)); } }
/// Returns point between two at given distance in percents. static GeoCoordinate newPoint(const GeoCoordinate &p1, const GeoCoordinate &p2, double distanceInProcents) { return GeoCoordinate(p1.latitude + (p2.latitude - p1.latitude)*distanceInProcents, p1.longitude + (p2.longitude - p1.longitude)*distanceInProcents); }