Example #1
0
static NValue polygonFromText(const std::string &wkt, bool doValidation)
{
    // Discard whitespace, but return commas or parentheses as tokens
    Tokenizer tokens(wkt, boost::char_separator<char>(" \f\n\r\t\v", ",()"));
    Tokenizer::iterator it = tokens.begin();
    Tokenizer::iterator end = tokens.end();

    if (! boost::iequals(*it, "polygon")) {
        throwInvalidWktPoly("does not start with POLYGON keyword");
    }
    ++it;

    if (! boost::iequals(*it, "(")) {
        throwInvalidWktPoly("missing left parenthesis after POLYGON keyword");
    }
    ++it;

    bool is_shell = true;
    std::size_t length = Polygon::serializedLengthNoLoops();
    std::vector<std::unique_ptr<S2Loop> > loops;
    while (it != end) {
        loops.push_back(std::unique_ptr<S2Loop>(new S2Loop()));
        readLoop(is_shell, wkt, it, end, loops.back().get());
        // Only the first loop is a shell.
        is_shell = false;
        length += Loop::serializedLength(loops.back()->num_vertices());
        if (*it == ",") {
            ++it;
        }
        else if (*it == ")") {
            ++it;
            break;
        }
        else {
            throwInvalidWktPoly("unexpected token: '" + (*it) + "'");
        }
    }

    if (it != end) {
        // extra stuff after input
        throwInvalidWktPoly("unrecognized input after WKT: '" + (*it) + "'");
    }

    NValue nval = ValueFactory::getUninitializedTempGeographyValue(length);
    char* storage = const_cast<char*>(ValuePeeker::peekObjectValue(nval));

    Polygon poly;
    poly.init(&loops); // polygon takes ownership of loops here.
    if (doValidation) {
        std::stringstream validReason;
        if (!poly.IsValid(&validReason)
                || isMultiPolygon(poly, &validReason)) {
            throwInvalidWktPoly(validReason.str());
        }
    }
    SimpleOutputSerializer output(storage, length);
    poly.saveToBuffer(output);
    return nval;
}
Example #2
0
template<> NValue NValue::callUnary<FUNC_VOLT_VALIDATE_POLYGON>() const {
    assert(getValueType() == VALUE_TYPE_GEOGRAPHY);
    if (isNull()) {
        return NValue::getNullValue(VALUE_TYPE_BOOLEAN);
    }
    // Be optimistic.
    bool returnval = true;
    // Extract the polygon and check its validity.
    Polygon poly;
    poly.initFromGeography(getGeographyValue());
    if (!poly.IsValid()
            || isMultiPolygon(poly)) {
        returnval = false;
    }
    return ValueFactory::getBooleanValue(returnval);
}
Example #3
0
template<> NValue NValue::callUnary<FUNC_VOLT_POLYGON_INVALID_REASON>() const {
    assert(getValueType() == VALUE_TYPE_GEOGRAPHY);
    if (isNull()) {
        return NValue::getNullValue(VALUE_TYPE_VARCHAR);
    }
    // Extract the polygon and check its validity.
    std::stringstream msg;
    Polygon poly;
    poly.initFromGeography(getGeographyValue());
    if (poly.IsValid(&msg)) {
        isMultiPolygon(poly, &msg);
    }
    std::string res (msg.str());
    if (res.size() == 0) {
        res = std::string("Valid Polygon");
    }
    return getTempStringValue(res.c_str(),res.length());
}
Example #4
0
    bool GeoParser::isGeometryCollection(const BSONObj &obj) {
        BSONElement type = obj.getFieldDotted(GEOJSON_TYPE);
        if (type.eoo() || (String != type.type())) { return false; }
        if (GEOJSON_TYPE_GEOMETRY_COLLECTION != type.String()) { return false; }

        BSONElement coordElt = obj.getFieldDotted(GEOJSON_GEOMETRIES);
        if (coordElt.eoo() || (Array != coordElt.type())) { return false; }

        const vector<BSONElement>& coordinates = coordElt.Array();
        if (0 == coordinates.size()) { return false; }

        for (size_t i = 0; i < coordinates.size(); ++i) {
            if (coordinates[i].eoo() || (Object != coordinates[i].type())) { return false; }
            BSONObj obj = coordinates[i].Obj();
            if (!isGeoJSONPoint(obj) && !isLine(obj) && !isGeoJSONPolygon(obj)
                && !isMultiPoint(obj) && !isMultiPolygon(obj) && !isMultiLine(obj)) {
                return false;
            }
        }

        return true;
    }
Example #5
0
    bool GeoParser::parseGeometryCollection(const BSONObj &obj, GeometryCollection *out) {
        BSONElement coordElt = obj.getFieldDotted(GEOJSON_GEOMETRIES);
        const vector<BSONElement>& geometries = coordElt.Array();

        for (size_t i = 0; i < geometries.size(); ++i) {
            const BSONObj& geoObj = geometries[i].Obj();

            if (isGeoJSONPoint(geoObj)) {
                PointWithCRS point;
                if (!parsePoint(geoObj, &point)) { return false; }
                out->points.push_back(point);
            } else if (isLine(geoObj)) {
                out->lines.mutableVector().push_back(new LineWithCRS());
                if (!parseLine(geoObj, out->lines.vector().back())) { return false; }
            } else if (isGeoJSONPolygon(geoObj)) {
                out->polygons.mutableVector().push_back(new PolygonWithCRS());
                if (!parsePolygon(geoObj, out->polygons.vector().back())) { return false; }
            } else if (isMultiPoint(geoObj)) {
                out->multiPoints.mutableVector().push_back(new MultiPointWithCRS());
                if (!parseMultiPoint(geoObj, out->multiPoints.mutableVector().back())) {
                    return false;
                }
            } else if (isMultiPolygon(geoObj)) {
                out->multiPolygons.mutableVector().push_back(new MultiPolygonWithCRS());
                if (!parseMultiPolygon(geoObj, out->multiPolygons.mutableVector().back())) {
                    return false;
                }
            } else {
                verify(isMultiLine(geoObj));
                out->multiLines.mutableVector().push_back(new MultiLineWithCRS());
                if (!parseMultiLine(geoObj, out->multiLines.mutableVector().back())) {
                    return false;
                }
            }
        }

        return true;
    }