Пример #1
0
template<> NValue NValue::callUnary<FUNC_VOLT_POLYGONFROMTEXT>() const
{
    bool is_shell = true;
    if (isNull()) {
        return NValue::getNullValue(VALUE_TYPE_GEOGRAPHY);
    }

    int32_t textLength;
    const char* textData = getObject_withoutNull(&textLength);
    const std::string wkt(textData, textLength);

    // 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;

    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.
    SimpleOutputSerializer output(storage, length);
    poly.saveToBuffer(output);
    return nval;
}
Пример #2
0
template<> NValue NValue::callUnary<FUNC_VOLT_POINTFROMTEXT>() const
{
    if (isNull()) {
        return NValue::getNullValue(VALUE_TYPE_POINT);
    }

    int32_t textLength;
    const char* textData = getObject_withoutNull(&textLength);
    std::string wkt(textData, textLength);

    // 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, "point")) {
        throwInvalidWktPoint(wkt);
    }
    ++it;

    if (! boost::iequals(*it, "(")) {
        throwInvalidWktPoint(wkt);
    }
    ++it;


    GeographyPointValue::Coord lng = stringToCoord(POINT, wkt, *it);
    ++it;

    GeographyPointValue::Coord lat = stringToCoord(POINT, wkt, *it);
    ++it;

    if ( lng < -180.0 || lng > 180.0) {
        throwInvalidPointLongitude(wkt);
    }

    if (lat < -90.0 || lat > 90.0 ) {
        throwInvalidPointLatitude(wkt);
    }

    if (! boost::iequals(*it, ")")) {
        throwInvalidWktPoint(wkt);
    }
    ++it;

    if (it != end) {
        throwInvalidWktPoint(wkt);
    }

    NValue returnValue(VALUE_TYPE_POINT);
    returnValue.getGeographyPointValue() = GeographyPointValue(lng, lat);

    return returnValue;
}
Пример #3
0
template<> NValue NValue::callUnary<FUNC_VOLT_POLYGONFROMVALIDTEXT>() const
{
    if (isNull()) {
        return NValue::getNullValue(VALUE_TYPE_GEOGRAPHY);
    }

    int32_t textLength;
    const char* textData = getObject_withoutNull(&textLength);
    const std::string wkt(textData, textLength);

    return polygonFromText(wkt, true);
}
Пример #4
0
/*
 * Produce a debugging string describing an NValue.
 */
std::string NValue::debug() const {
    const ValueType type = getValueType();
    if (isNull()) {
        return "<NULL>";
    }
    std::ostringstream buffer;
    std::string out_val;
    const char* ptr;
    int64_t addr;
    buffer << getTypeName(type) << "::";
    switch (type) {
    case VALUE_TYPE_BOOLEAN:
        buffer << (getBoolean() ? "true" : "false");
        break;
    case VALUE_TYPE_TINYINT:
        buffer << static_cast<int32_t>(getTinyInt());
        break;
    case VALUE_TYPE_SMALLINT:
        buffer << getSmallInt();
        break;
    case VALUE_TYPE_INTEGER:
        buffer << getInteger();
        break;
    case VALUE_TYPE_BIGINT:
        buffer << getBigInt();
        break;
    case VALUE_TYPE_DOUBLE:
        buffer << getDouble();
        break;
    case VALUE_TYPE_VARCHAR:
    {
        int32_t length;
        ptr = getObject_withoutNull(&length);
        addr = reinterpret_cast<int64_t>(ptr);
        out_val = std::string(ptr, length);
        buffer << "[" << length << "]";
        buffer << "\"" << out_val << "\"[@" << addr << "]";
        break;
    }
    case VALUE_TYPE_VARBINARY:
    {
        int32_t length;
        ptr = getObject_withoutNull(&length);
        addr = reinterpret_cast<int64_t>(ptr);
        out_val = std::string(ptr, length);
        buffer << "[" << length << "]";
        buffer << "-bin[@" << addr << "]";
        break;
    }
    case VALUE_TYPE_DECIMAL:
        buffer << createStringFromDecimal();
        break;
    case VALUE_TYPE_TIMESTAMP: {
        try {
            std::stringstream ss;
            streamTimestamp(ss);
            buffer << ss.str();
        }
        catch (const SQLException &) {
            buffer << "<out of range timestamp:" << getBigInt() << ">";
        }
        catch (...) {
            buffer << "<exception when converting timestamp:" << getBigInt() << ">";
        }
        break;
    }
    case VALUE_TYPE_POINT:
        buffer << getGeographyPointValue().toString();
        break;
    case VALUE_TYPE_GEOGRAPHY:
        buffer << getGeographyValue().toString();
        break;
    default:
        buffer << "(no details)";
        break;
    }
    std::string ret(buffer.str());
    return (ret);
}