| 340 | |
| 341 | |
| 342 | void Ilvis2MetadataReader::parseGPolygon(xmlNodePtr node, MetadataNode * m) |
| 343 | { |
| 344 | assertElementIs(node, "GPolygon"); |
| 345 | |
| 346 | xmlNodePtr child = getFirstChildElementNode(node); |
| 347 | assertElementIs(child, "Boundary"); |
| 348 | |
| 349 | // The number of boundaries is essentially the number of sub-polygons |
| 350 | int numBoundaries = countChildElements(node, "Boundary"); |
| 351 | |
| 352 | // NOTE: Ownership of these rings is transferred to an OGR geometry and |
| 353 | // deleted with that geometry. |
| 354 | std::vector<OGRLinearRing *> rings; |
| 355 | while (nodeElementIs(child, "Boundary")) |
| 356 | { |
| 357 | // There must be at least 3 points to be valid per the schema. |
| 358 | int numPoints = countChildElements(child, "Point"); |
| 359 | if (numPoints < 3) |
| 360 | throw error("Found a polygon boundary with less than 3 points, " |
| 361 | "invalid for this schema"); |
| 362 | |
| 363 | xmlNodePtr bdChild = getFirstChildElementNode(child); |
| 364 | |
| 365 | OGRLinearRing *lr = new OGRLinearRing(); |
| 366 | while (nodeElementIs(bdChild, "Point")) |
| 367 | { |
| 368 | xmlNodePtr ptChild = getFirstChildElementNode(bdChild); |
| 369 | assertElementIs(ptChild, "PointLongitude"); |
| 370 | double ptLon = extractDouble(ptChild); |
| 371 | |
| 372 | ptChild = getNextElementNode(ptChild); |
| 373 | assertElementIs(ptChild, "PointLatitude"); |
| 374 | double ptLat = extractDouble(ptChild); |
| 375 | |
| 376 | ptChild = getNextElementNode(ptChild); |
| 377 | assertEndOfElements(ptChild); |
| 378 | |
| 379 | lr->addPoint(ptLon, ptLat); |
| 380 | |
| 381 | bdChild = getNextElementNode(bdChild); |
| 382 | } |
| 383 | lr->closeRings(); |
| 384 | rings.push_back(lr); |
| 385 | child = getNextElementNode(child); |
| 386 | } |
| 387 | |
| 388 | assertEndOfElements(child); |
| 389 | |
| 390 | // If only one sub-polygon, just make a POLYGON WKT, |
| 391 | // else make it a MULTIPOLYGON |
| 392 | std::unique_ptr<OGRGeometry> geom; |
| 393 | if (numBoundaries > 1) |
| 394 | { |
| 395 | OGRMultiPolygon *mp = new OGRMultiPolygon(); |
| 396 | for (auto lr : rings) |
| 397 | mp->addGeometryDirectly(lr); |
| 398 | geom.reset(mp); |
| 399 | } |