本文整理汇总了C++中GeometryCoordinates类的典型用法代码示例。如果您正苦于以下问题:C++ GeometryCoordinates类的具体用法?C++ GeometryCoordinates怎么用?C++ GeometryCoordinates使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了GeometryCoordinates类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: resample
Anchors resample(const GeometryCoordinates &line, const float offset, const float spacing,
const float angleWindowSize, const float maxAngle, const float labelLength, const bool continuedLine, const bool placeAtMiddle) {
const float halfLabelLength = labelLength / 2.0f;
float lineLength = 0;
for (auto it = line.begin(), end = line.end() - 1; it != end; it++) {
lineLength += util::dist<float>(*(it), *(it + 1));
}
float distance = 0;
float markedDistance = offset - spacing;
Anchors anchors;
assert(spacing > 0.0);
int i = 0;
for (auto it = line.begin(), end = line.end() - 1; it != end; it++, i++) {
const GeometryCoordinate &a = *(it);
const GeometryCoordinate &b = *(it + 1);
const float segmentDist = util::dist<float>(a, b);
const float angle = util::angle_to(b, a);
while (markedDistance + spacing < distance + segmentDist) {
markedDistance += spacing;
float t = (markedDistance - distance) / segmentDist,
x = util::interpolate(float(a.x), float(b.x), t),
y = util::interpolate(float(a.y), float(b.y), t);
// Check that the point is within the tile boundaries and that
// the label would fit before the beginning and end of the line
// if placed at this point.
if (x >= 0 && x < util::EXTENT && y >= 0 && y < util::EXTENT &&
markedDistance - halfLabelLength >= 0.0f &&
markedDistance + halfLabelLength <= lineLength) {
Anchor anchor(::round(x), ::round(y), angle, 0.5f, i);
if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) {
anchors.push_back(anchor);
}
}
}
distance += segmentDist;
}
if (!placeAtMiddle && anchors.empty() && !continuedLine) {
// The first attempt at finding anchors at which labels can be placed failed.
// Try again, but this time just try placing one anchor at the middle of the line.
// This has the most effect for short lines in overscaled tiles, since the
// initial offset used in overscaled tiles is calculated to align labels with positions in
// parent tiles instead of placing the label as close to the beginning as possible.
anchors = resample(line, distance / 2, spacing, angleWindowSize, maxAngle, labelLength, continuedLine, true);
}
return anchors;
}
示例2: operator
GeometryCollection operator()(const mapbox::geometry::line_string<int16_t>& geom) const {
GeometryCoordinates coordinates;
coordinates.reserve(geom.size());
for (const auto& point : geom) {
coordinates.emplace_back(point);
}
return { coordinates };
}
示例3: getSegmentGlyphs
void getSegmentGlyphs(std::back_insert_iterator<GlyphInstances> glyphs, Anchor &anchor,
float offset, const GeometryCoordinates &line, int segment, bool forward) {
const bool upsideDown = !forward;
if (offset < 0)
forward = !forward;
if (forward)
segment++;
assert((int)line.size() > segment);
vec2<float> end = line[segment];
vec2<float> newAnchorPoint = anchor;
float prevscale = std::numeric_limits<float>::infinity();
offset = std::fabs(offset);
const float placementScale = anchor.scale;
while (true) {
const float dist = util::dist<float>(newAnchorPoint, end);
const float scale = offset / dist;
float angle = std::atan2(end.y - newAnchorPoint.y, end.x - newAnchorPoint.x);
if (!forward)
angle += M_PI;
if (upsideDown)
angle += M_PI;
glyphs = GlyphInstance{
/* anchor */ newAnchorPoint,
/* offset */ static_cast<float>(upsideDown ? M_PI : 0.0),
/* minScale */ scale,
/* maxScale */ prevscale,
/* angle */ static_cast<float>(std::fmod((angle + 2.0 * M_PI), (2.0 * M_PI)))};
if (scale <= placementScale)
break;
newAnchorPoint = end;
// skip duplicate nodes
while (newAnchorPoint == end) {
segment += forward ? 1 : -1;
if ((int)line.size() <= segment || segment < 0) {
anchor.scale = scale;
return;
}
end = line[segment];
}
vec2<float> normal = util::normal<float>(newAnchorPoint, end) * dist;
newAnchorPoint = newAnchorPoint - normal;
prevscale = scale;
}
}
示例4: polygonContainsPoint
bool polygonContainsPoint(const GeometryCoordinates& ring, const GeometryCoordinate& p) {
bool c = false;
for (auto i = ring.begin(), j = ring.end() - 1; i != ring.end(); j = i++) {
auto& p1 = *i;
auto& p2 = *j;
if (((p1.y > p.y) != (p2.y > p.y)) && (p.x < float(p2.x - p1.x) * float(p.y - p1.y) / float(p2.y - p1.y) + p1.x)) {
c = !c;
}
}
return c;
}
示例5:
std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRenderedFeatures(const QueryParameters& parameters) const {
std::unordered_map<std::string, std::vector<Feature>> result;
if (renderTiles.empty() || parameters.geometry.empty()) {
return result;
}
LineString<double> queryGeometry;
for (const auto& p : parameters.geometry) {
queryGeometry.push_back(TileCoordinate::fromScreenCoordinate(
parameters.transformState, 0, { p.x, parameters.transformState.getSize().height - p.y }).p);
}
mapbox::geometry::box<double> box = mapbox::geometry::envelope(queryGeometry);
auto sortRenderTiles = [](const RenderTile& a, const RenderTile& b) {
return a.id.canonical.z != b.id.canonical.z ? a.id.canonical.z < b.id.canonical.z :
a.id.canonical.y != b.id.canonical.y ? a.id.canonical.y < b.id.canonical.y :
a.id.wrap != b.id.wrap ? a.id.wrap < b.id.wrap : a.id.canonical.x < b.id.canonical.x;
};
std::vector<std::reference_wrapper<const RenderTile>> sortedTiles;
std::transform(renderTiles.cbegin(), renderTiles.cend(), std::back_inserter(sortedTiles),
[](const auto& pair) { return std::ref(pair.second); });
std::sort(sortedTiles.begin(), sortedTiles.end(), sortRenderTiles);
for (const auto& renderTileRef : sortedTiles) {
const RenderTile& renderTile = renderTileRef.get();
GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min);
if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT) {
continue;
}
GeometryCoordinate tileSpaceBoundsMax = TileCoordinate::toGeometryCoordinate(renderTile.id, box.max);
if (tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) {
continue;
}
GeometryCoordinates tileSpaceQueryGeometry;
tileSpaceQueryGeometry.reserve(queryGeometry.size());
for (const auto& c : queryGeometry) {
tileSpaceQueryGeometry.push_back(TileCoordinate::toGeometryCoordinate(renderTile.id, c));
}
renderTile.tile.queryRenderedFeatures(result,
tileSpaceQueryGeometry,
parameters.transformState,
parameters.layerIDs);
}
return result;
}
示例6: pointIntersectsBufferedLine
bool pointIntersectsBufferedLine(const GeometryCoordinate& p, const GeometryCoordinates& line, const float radius) {
const float radiusSquared = radius * radius;
if (line.size() == 1) return util::distSqr<float>(p, line.at(0)) < radiusSquared;
if (line.size() == 0) return false;
for (auto i = line.begin() + 1; i != line.end(); i++) {
// Find line segments that have a distance <= radius^2 to p
// In that case, we treat the line as "containing point p".
auto& v = *(i - 1);
auto& w = *i;
if (distToSegmentSquared(p, v, w) < radiusSquared) return true;
}
return false;
}
示例7: bboxifyLabel
void CollisionFeature::bboxifyLabel(const GeometryCoordinates &line,
GeometryCoordinate &anchorPoint, const int segment, const float labelLength, const float boxSize) {
const float step = boxSize / 2;
const unsigned int nBoxes = std::floor(labelLength / step);
// offset the center of the first box by half a box so that the edge of the
// box is at the edge of the label.
const float firstBoxOffset = -boxSize / 2;
GeometryCoordinate &p = anchorPoint;
int index = segment + 1;
float anchorDistance = firstBoxOffset;
// move backwards along the line to the first segment the label appears on
do {
index--;
// there isn't enough room for the label after the beginning of the line
// checkMaxAngle should have already caught this
if (index < 0) return;
anchorDistance -= util::dist<float>(line[index], p);
p = line[index];
} while (anchorDistance > -labelLength / 2);
float segmentLength = util::dist<float>(line[index], line[index + 1]);
for (unsigned int i = 0; i < nBoxes; i++) {
// the distance the box will be from the anchor
const float boxDistanceToAnchor = -labelLength / 2 + i * step;
// the box is not on the current segment. Move to the next segment.
while (anchorDistance + segmentLength < boxDistanceToAnchor) {
anchorDistance += segmentLength;
index++;
// There isn't enough room before the end of the line.
if (index + 1 >= (int)line.size()) return;
segmentLength = util::dist<float>(line[index], line[index + 1]);
}
// the distance the box will be from the beginning of the segment
const float segmentBoxDistance = boxDistanceToAnchor - anchorDistance;
const auto& p0 = line[index];
const auto& p1 = line[index + 1];
Point<float> boxAnchor = {
p0.x + segmentBoxDistance / segmentLength * (p1.x - p0.x),
p0.y + segmentBoxDistance / segmentLength * (p1.y - p0.y)
};
const float distanceToInnerEdge = std::max(std::fabs(boxDistanceToAnchor - firstBoxOffset) - step / 2, 0.0f);
const float maxScale = labelLength / 2 / distanceToInnerEdge;
boxes.emplace_back(boxAnchor, -boxSize / 2, -boxSize / 2, boxSize / 2, boxSize / 2, maxScale);
}
}
示例8: getNextVirtualSegment
optional<VirtualSegment> getNextVirtualSegment(const VirtualSegment& previousVirtualSegment,
const GeometryCoordinates& line,
const float glyphDistanceFromAnchor,
const bool glyphIsLogicallyForward) {
auto nextSegmentBegin = previousVirtualSegment.end;
auto end = nextSegmentBegin;
size_t index = previousVirtualSegment.index;
// skip duplicate nodes
while (end == nextSegmentBegin) {
// look ahead by 2 points in the line because the segment index refers to the beginning
// of the segment, and we need an endpoint too
if (glyphIsLogicallyForward && (index + 2 < line.size())) {
index += 1;
} else if (!glyphIsLogicallyForward && index != 0) {
index -= 1;
} else {
return {};
}
end = getSegmentEnd(glyphIsLogicallyForward, line, index);
}
const auto anchor = getVirtualSegmentAnchor(nextSegmentBegin, end,
util::dist<float>(previousVirtualSegment.anchor,
previousVirtualSegment.end));
return VirtualSegment {
anchor,
end,
index,
getMinScaleForSegment(glyphDistanceFromAnchor, anchor, end),
previousVirtualSegment.minScale
};
}
示例9: getIconQuads
SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon,
const GeometryCoordinates& line, const SymbolLayoutProperties& layout,
const bool alongLine) {
auto image = *(shapedIcon.image);
const float border = 1.0;
auto left = shapedIcon.left - border;
auto right = left + image.pos.w / image.relativePixelRatio;
auto top = shapedIcon.top - border;
auto bottom = top + image.pos.h / image.relativePixelRatio;
vec2<float> tl{left, top};
vec2<float> tr{right, top};
vec2<float> br{right, bottom};
vec2<float> bl{left, bottom};
float angle = layout.icon.rotate * util::DEG2RAD;
if (alongLine) {
assert(static_cast<unsigned int>(anchor.segment) < line.size());
const GeometryCoordinate &prev= line[anchor.segment];
if (anchor.y == prev.y && anchor.x == prev.x &&
static_cast<unsigned int>(anchor.segment + 1) < line.size()) {
const GeometryCoordinate &next= line[anchor.segment + 1];
angle += std::atan2(anchor.y - next.y, anchor.x - next.x) + M_PI;
} else {
angle += std::atan2(anchor.y - prev.y, anchor.x - prev.x);
}
}
if (angle) {
// Compute the transformation matrix.
float angle_sin = std::sin(angle);
float angle_cos = std::cos(angle);
std::array<float, 4> matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}};
tl = tl.matMul(matrix);
tr = tr.matMul(matrix);
bl = bl.matMul(matrix);
br = br.matMul(matrix);
}
SymbolQuads quads;
quads.emplace_back(tl, tr, bl, br, image.pos, 0, anchor, globalMinScale, std::numeric_limits<float>::infinity());
return quads;
}
示例10: toClipperPath
static ClipperLib::Path toClipperPath(const GeometryCoordinates& ring) {
ClipperLib::Path result;
result.reserve(ring.size());
for (const auto& p : ring) {
result.emplace_back(p.x, p.y);
}
return result;
}
示例11: polygonIntersectsBox
bool polygonIntersectsBox(const LineString<float>& polygon, const GridIndex<IndexedSubfeature>::BBox& bbox) {
// This is just a wrapper that allows us to use the integer-based util::polygonIntersectsPolygon
// Conversion limits our query accuracy to single-pixel resolution
GeometryCoordinates integerPolygon;
for (const auto& point : polygon) {
integerPolygon.push_back(convertPoint<int16_t>(point));
}
int16_t minX1 = bbox.min.x;
int16_t maxY1 = bbox.max.y;
int16_t minY1 = bbox.min.y;
int16_t maxX1 = bbox.max.x;
auto bboxPoints = GeometryCoordinates {
{ minX1, minY1 }, { maxX1, minY1 }, { maxX1, maxY1 }, { minX1, maxY1 }
};
return util::polygonIntersectsPolygon(integerPolygon, bboxPoints);
}
示例12: float
GeometryCollection VectorTileFeature::getGeometries() const {
uint8_t cmd = 1;
uint32_t length = 0;
int32_t x = 0;
int32_t y = 0;
const float scale = float(util::EXTENT) / layer.extent;
GeometryCollection lines;
lines.emplace_back();
GeometryCoordinates* line = &lines.back();
auto g_itr = geometry_iter.begin();
while (g_itr != geometry_iter.end()) {
if (length == 0) {
uint32_t cmd_length = static_cast<uint32_t>(*g_itr++);
cmd = cmd_length & 0x7;
length = cmd_length >> 3;
}
--length;
if (cmd == 1 || cmd == 2) {
x += protozero::decode_zigzag32(static_cast<uint32_t>(*g_itr++));
y += protozero::decode_zigzag32(static_cast<uint32_t>(*g_itr++));
if (cmd == 1 && !line->empty()) { // moveTo
lines.emplace_back();
line = &lines.back();
}
line->emplace_back(::round(x * scale), ::round(y * scale));
} else if (cmd == 7) { // closePolygon
if (!line->empty()) {
line->push_back((*line)[0]);
}
} else {
throw std::runtime_error("unknown command");
}
}
示例13: signedArea
static double signedArea(const GeometryCoordinates& ring) {
double sum = 0;
for (std::size_t i = 0, len = ring.size(), j = len - 1; i < len; j = i++) {
const GeometryCoordinate& p1 = ring[i];
const GeometryCoordinate& p2 = ring[j];
sum += (p2.x - p1.x) * (p1.y + p2.y);
}
return sum;
}
示例14: data
GeometryCollection VectorTileFeature::getGeometries() const {
pbf data(geometry_pbf);
uint8_t cmd = 1;
uint32_t length = 0;
int32_t x = 0;
int32_t y = 0;
GeometryCollection lines;
lines.emplace_back();
GeometryCoordinates* line = &lines.back();
while (data.data < data.end) {
if (length == 0) {
uint32_t cmd_length = data.varint();
cmd = cmd_length & 0x7;
length = cmd_length >> 3;
}
--length;
if (cmd == 1 || cmd == 2) {
x += data.svarint();
y += data.svarint();
if (cmd == 1 && !line->empty()) { // moveTo
lines.emplace_back();
line = &lines.back();
}
line->emplace_back(x, y);
} else if (cmd == 7) { // closePolygon
if (!line->empty()) {
line->push_back((*line)[0]);
}
} else {
throw std::runtime_error("unknown command");
}
}
示例15: translateVec
optional<GeometryCoordinates> FeatureIndex::translateQueryGeometry(
const GeometryCoordinates& queryGeometry,
const std::array<float, 2>& translate,
const style::TranslateAnchorType anchorType,
const float bearing,
const float pixelsToTileUnits) {
if (translate[0] == 0 && translate[1] == 0) {
return {};
}
GeometryCoordinate translateVec(translate[0] * pixelsToTileUnits, translate[1] * pixelsToTileUnits);
if (anchorType == style::TranslateAnchorType::Viewport) {
translateVec = util::rotate(translateVec, -bearing);
}
GeometryCoordinates translated;
for (const auto& p : queryGeometry) {
translated.push_back(p - translateVec);
}
return translated;
}