mirror of https://gitee.com/bigwinds/arangodb
added MultiPolygon GeoJSON constructor function (#7633)
This commit is contained in:
parent
fd78c7a1e3
commit
442d59a3f8
|
@ -277,6 +277,32 @@ RETURN GEO_POLYGON([
|
|||
@END_EXAMPLE_AQL
|
||||
@endDocuBlock aqlGeoPolygon_2
|
||||
|
||||
### GEO_MULTIPOLYGON()
|
||||
|
||||
`GEO_MULTIPOLYGON(polygons) → geoJson`
|
||||
|
||||
Construct a GeoJSON MultiPolygon. Needs at least two polygons in an array (You
|
||||
can find the rules for the Polygon construction above).
|
||||
|
||||
- **polygons** (array): array of polygons
|
||||
- returns **geoJson** (object|null): a valid GeoJSON Polygon
|
||||
|
||||
MultiPolygon:
|
||||
|
||||
@startDocuBlockInline aqlGeoMultiPolygon_1
|
||||
@EXAMPLE_AQL{aqlGeoMultiPolygon_1}
|
||||
RETURN GEO_MULTIPOLYGON([
|
||||
[
|
||||
[[40, 40], [20, 45], [45, 30], [40, 40]]
|
||||
],
|
||||
[
|
||||
[[20, 35], [10, 30], [10, 10], [30, 5], [45, 20], [20, 35]],
|
||||
[[30, 20], [20, 15], [20, 25], [30, 20]]
|
||||
]
|
||||
])
|
||||
@END_EXAMPLE_AQL
|
||||
@endDocuBlock aqlGeoMultiPolygon_1
|
||||
|
||||
Geo Index Functions
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -358,6 +358,7 @@ void AqlFunctionFeature::addGeometryConstructors() {
|
|||
add({"GEO_POINT", ".,.", flags, &Functions::GeoPoint});
|
||||
add({"GEO_MULTIPOINT", ".", flags, &Functions::GeoMultiPoint});
|
||||
add({"GEO_POLYGON", ".", flags, &Functions::GeoPolygon});
|
||||
add({"GEO_MULTIPOLYGON", ".", flags, &Functions::GeoMultiPolygon});
|
||||
add({"GEO_LINESTRING", ".", flags, &Functions::GeoLinestring});
|
||||
add({"GEO_MULTILINESTRING", ".", flags, &Functions::GeoMultiLinestring});
|
||||
}
|
||||
|
|
|
@ -5343,6 +5343,117 @@ AqlValue Functions::GeoPolygon(ExpressionContext* expressionContext,
|
|||
return AqlValue(b);
|
||||
}
|
||||
|
||||
// TODO: merge MULTIPOLYGON with POLYGON and reuse functions
|
||||
/// @brief function GEO_MULTIPOLYGON
|
||||
AqlValue Functions::GeoMultiPolygon(ExpressionContext* expressionContext,
|
||||
transaction::Methods* trx,
|
||||
VPackFunctionParameters const& parameters) {
|
||||
size_t const n = parameters.size();
|
||||
|
||||
if (n < 1) {
|
||||
// no parameters
|
||||
return AqlValue(AqlValueHintNull());
|
||||
}
|
||||
|
||||
AqlValue const& geoArray = extractFunctionParameterValue(parameters, 0);
|
||||
|
||||
if (!geoArray.isArray()) {
|
||||
::registerWarning(expressionContext, "GEO_MULTIPOLYGON",
|
||||
TRI_ERROR_QUERY_ARRAY_EXPECTED);
|
||||
return AqlValue(arangodb::velocypack::Slice::nullSlice());
|
||||
}
|
||||
|
||||
VPackBuilder b;
|
||||
b.openObject();
|
||||
b.add("type", VPackValue("MultiPolygon"));
|
||||
b.add("coordinates", VPackValue(VPackValueType::Array));
|
||||
|
||||
AqlValueMaterializer materializer(trx);
|
||||
VPackSlice s = materializer.slice(geoArray, false);
|
||||
|
||||
/*
|
||||
return GEO_MULTIPOLYGON([
|
||||
[
|
||||
[[40, 40], [20, 45], [45, 30], [40, 40]]
|
||||
],
|
||||
[
|
||||
[[20, 35], [10, 30], [10, 10], [30, 5], [45, 20], [20, 35]],
|
||||
[[30, 20], [20, 15], [20, 25], [30, 20]]
|
||||
]
|
||||
])
|
||||
*/
|
||||
|
||||
if (s.isArray() && s.length() < 2) {
|
||||
::registerWarning(expressionContext, "GEO_MULTIPOLYGON", Result(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH,
|
||||
"a MultiPolygon needs at least two Polygons inside."));
|
||||
return AqlValue(arangodb::velocypack::Slice::nullSlice());
|
||||
}
|
||||
|
||||
for (auto const& arrayOfPolygons : VPackArrayIterator(s)) {
|
||||
b.openArray();
|
||||
for (auto const& v : VPackArrayIterator(arrayOfPolygons)) {
|
||||
if (v.isArray() && v.length() > 2) {
|
||||
b.openArray();
|
||||
for (auto const& coord : VPackArrayIterator(v)) {
|
||||
if (coord.isNumber()) {
|
||||
b.add(VPackValue(coord.getNumber<double>()));
|
||||
} else if (coord.isArray()) {
|
||||
if (coord.length() < 2) {
|
||||
::registerWarning(expressionContext, "GEO_MULTIPOLYGON", Result(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH,
|
||||
"a Position needs at least two numeric values"));
|
||||
return AqlValue(arangodb::velocypack::Slice::nullSlice());
|
||||
} else {
|
||||
b.openArray();
|
||||
for (auto const& innercord : VPackArrayIterator(coord)) {
|
||||
if (innercord.isNumber()) {
|
||||
b.add(VPackValue(innercord.getNumber<double>()));
|
||||
} else if (innercord.isArray()) {
|
||||
if (innercord.at(0).isNumber() && innercord.at(1).isNumber()) {
|
||||
b.openArray();
|
||||
b.add(VPackValue(innercord.at(0).getNumber<double>()));
|
||||
b.add(VPackValue(innercord.at(1).getNumber<double>()));
|
||||
b.close();
|
||||
} else {
|
||||
::registerWarning(expressionContext, "GEO_MULTIPOLYGON", Result(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH,
|
||||
"not a number"));
|
||||
return AqlValue(arangodb::velocypack::Slice::nullSlice());
|
||||
}
|
||||
} else {
|
||||
::registerWarning(expressionContext, "GEO_MULTIPOLYGON", Result(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH,
|
||||
"not an array describing a position"));
|
||||
return AqlValue(arangodb::velocypack::Slice::nullSlice());
|
||||
}
|
||||
}
|
||||
b.close();
|
||||
}
|
||||
} else {
|
||||
::registerWarning(expressionContext, "GEO_MULTIPOLYGON", Result(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH,
|
||||
"not an array containing positions"));
|
||||
return AqlValue(arangodb::velocypack::Slice::nullSlice());
|
||||
}
|
||||
}
|
||||
b.close();
|
||||
} else {
|
||||
::registerWarning(expressionContext, "GEO_MULTIPOLYGON", Result(
|
||||
TRI_ERROR_QUERY_FUNCTION_ARGUMENT_TYPE_MISMATCH,
|
||||
"not an array containing positions"));
|
||||
return AqlValue(arangodb::velocypack::Slice::nullSlice());
|
||||
}
|
||||
}
|
||||
b.close();
|
||||
}
|
||||
|
||||
b.close();
|
||||
b.close();
|
||||
|
||||
return AqlValue(b);
|
||||
}
|
||||
|
||||
/// @brief function GEO_LINESTRING
|
||||
AqlValue Functions::GeoLinestring(ExpressionContext* expressionContext,
|
||||
transaction::Methods* trx,
|
||||
|
|
|
@ -319,6 +319,8 @@ struct Functions {
|
|||
VPackFunctionParameters const&);
|
||||
static AqlValue GeoPolygon(arangodb::aql::ExpressionContext*, transaction::Methods*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue GeoMultiPolygon(arangodb::aql::ExpressionContext*, transaction::Methods*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue GeoLinestring(arangodb::aql::ExpressionContext*, transaction::Methods*,
|
||||
VPackFunctionParameters const&);
|
||||
static AqlValue GeoMultiLinestring(arangodb::aql::ExpressionContext*, transaction::Methods*,
|
||||
|
|
Loading…
Reference in New Issue