blob: 8f28500eeeedbb16ffc0a1b82e152f8da1ba39c1 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "geo/geo_types.h"
#include <gtest/gtest.h>
#include "common/logging.h"
#include "geo/geo_types.h"
#include "geo/wkt_parse.h"
#include "geo/wkt_parse_ctx.h"
#include "s2/s2debug.h"
namespace doris {
class GeoTypesTest : public testing::Test {
public:
GeoTypesTest() {}
virtual ~GeoTypesTest() {}
};
TEST_F(GeoTypesTest, point_normal) {
{
GeoPoint point;
auto status = point.from_coord(116.123, 63.546);
ASSERT_EQ(GEO_PARSE_OK, status);
ASSERT_STREQ("POINT (116.123 63.546)", point.as_wkt().c_str());
std::string buf;
point.encode_to(&buf);
{
std::unique_ptr<GeoShape> point2(GeoShape::from_encoded(buf.data(), buf.size()));
ASSERT_STREQ("POINT (116.123 63.546)", point2->as_wkt().c_str());
}
{
buf.resize(buf.size() - 1);
std::unique_ptr<GeoShape> point2(GeoShape::from_encoded(buf.data(), buf.size()));
ASSERT_EQ(nullptr, point2);
}
}
{
GeoPoint point;
GeoCoordinate coord;
coord.x = 116.123;
coord.y = 63.546;
auto status = point.from_coord(coord);
ASSERT_EQ(GEO_PARSE_OK, status);
ASSERT_STREQ("POINT (116.123 63.546)", point.as_wkt().c_str());
}
}
TEST_F(GeoTypesTest, point_invalid) {
GeoPoint point;
auto status = point.from_coord(200, 88);
ASSERT_NE(GEO_PARSE_OK, status);
}
TEST_F(GeoTypesTest, linestring) {
const char* wkt = "LINESTRING (30 10, 10 30, 40 40)";
GeoParseStatus status;
std::unique_ptr<GeoShape> line(GeoShape::from_wkt(wkt, strlen(wkt), &status));
ASSERT_NE(nullptr, line.get());
ASSERT_EQ(GEO_SHAPE_LINE_STRING, line->type());
ASSERT_STREQ(wkt, line->as_wkt().c_str());
std::string buf;
line->encode_to(&buf);
{
std::unique_ptr<GeoShape> line2(GeoShape::from_encoded(buf.data(), buf.size()));
ASSERT_STREQ(wkt, line2->as_wkt().c_str());
}
{
buf.resize(buf.size() - 1);
std::unique_ptr<GeoShape> line2(GeoShape::from_encoded(buf.data(), buf.size()));
ASSERT_EQ(nullptr, line2);
}
}
TEST_F(GeoTypesTest, polygon_contains) {
const char* wkt = "POLYGON ((10 10, 50 10, 50 10, 50 50, 50 50, 10 50, 10 10))";
GeoParseStatus status;
std::unique_ptr<GeoShape> polygon(GeoShape::from_wkt(wkt, strlen(wkt), &status));
ASSERT_NE(nullptr, polygon.get());
{
GeoPoint point;
point.from_coord(20, 20);
auto res = polygon->contains(&point);
ASSERT_TRUE(res);
}
{
GeoPoint point;
point.from_coord(5, 5);
auto res = polygon->contains(&point);
ASSERT_FALSE(res);
}
std::string buf;
polygon->encode_to(&buf);
{
std::unique_ptr<GeoShape> shape(GeoShape::from_encoded(buf.data(), buf.size()));
ASSERT_EQ(GEO_SHAPE_POLYGON, shape->type());
LOG(INFO) << "polygon=" << shape->as_wkt();
}
{
buf.resize(buf.size() - 1);
std::unique_ptr<GeoShape> shape(GeoShape::from_encoded(buf.data(), buf.size()));
ASSERT_EQ(nullptr, shape);
}
}
TEST_F(GeoTypesTest, polygon_parse_fail) {
{
const char* wkt = "POLYGON ((10 10, 50 10, 50 50, 10 50), (10 10 01))";
GeoParseStatus status;
std::unique_ptr<GeoShape> polygon(GeoShape::from_wkt(wkt, strlen(wkt), &status));
ASSERT_EQ(GEO_PARSE_WKT_SYNTAX_ERROR, status);
ASSERT_EQ(nullptr, polygon.get());
}
{
const char* wkt = "POLYGON ((10 10, 50 10, 50 50, 10 50))";
GeoParseStatus status;
std::unique_ptr<GeoShape> polygon(GeoShape::from_wkt(wkt, strlen(wkt), &status));
ASSERT_EQ(GEO_PARSE_LOOP_NOT_CLOSED, status);
ASSERT_EQ(nullptr, polygon.get());
}
{
const char* wkt = "POLYGON ((10 10, 50 10, 10 10))";
GeoParseStatus status;
std::unique_ptr<GeoShape> polygon(GeoShape::from_wkt(wkt, strlen(wkt), &status));
ASSERT_EQ(GEO_PARSE_LOOP_LACK_VERTICES, status);
ASSERT_EQ(nullptr, polygon.get());
}
}
TEST_F(GeoTypesTest, polygon_hole_contains) {
const char* wkt =
"POLYGON ((10 10, 50 10, 50 50, 10 50, 10 10), (20 20, 40 20, 40 40, 20 40, 20 20))";
GeoParseStatus status;
std::unique_ptr<GeoShape> polygon(GeoShape::from_wkt(wkt, strlen(wkt), &status));
ASSERT_EQ(GEO_PARSE_OK, status);
ASSERT_NE(nullptr, polygon);
{
GeoPoint point;
point.from_coord(15, 15);
auto res = polygon->contains(&point);
ASSERT_TRUE(res);
}
{
GeoPoint point;
point.from_coord(25, 25);
auto res = polygon->contains(&point);
ASSERT_FALSE(res);
}
{
GeoPoint point;
point.from_coord(20, 20);
auto res = polygon->contains(&point);
ASSERT_TRUE(res);
}
}
TEST_F(GeoTypesTest, circle) {
GeoCircle circle;
auto res = circle.init(110.123, 64, 1000);
ASSERT_EQ(GEO_PARSE_OK, res);
std::string buf;
circle.encode_to(&buf);
{
std::unique_ptr<GeoShape> circle2(GeoShape::from_encoded(buf.data(), buf.size()));
ASSERT_STREQ("CIRCLE ((110.123 64), 1000)", circle2->as_wkt().c_str());
}
{
buf.resize(buf.size() - 1);
std::unique_ptr<GeoShape> circle2(GeoShape::from_encoded(buf.data(), buf.size()));
ASSERT_EQ(nullptr, circle2);
}
}
} // namespace doris
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
FLAGS_s2debug = false;
return RUN_ALL_TESTS();
}