A node topology defines the interrelation of nodes (point objects). Node topologies often are used in conjunction with other topologies in analysis. Examples of node topologies include street lights, city-maintained trees, or drill holes for core samples. A network topology considers the interconnection of links (lines) forming a linear network. Links can connect nodes. Examples of network topologies include a street network and a water-distribution application that traces the flow of water from a pumping station to residences. A polygon topology defines polygons that represent enclosed areas such as land parcels and census tracts. A single link defines the common boundary between adjacent areas. A polygon topology can be used for tax assessment and land planning in which parcels of land are represented by polygons. Polygon topologies can represent political boundaries, such as voting districts, city, state, or provincial boundaries, special districts, and school districts.
With topologies, you can perform spatial analyses such as:
Topology information is stored as object data on each element that makes up the topology. This data can be saved as part of the current map, or saved back to a source drawing. Because topology is definable for a map, identifiers used to store the topology are unique to the map. Topology in each drawing must be separate and unique. Autodesk Map does not support topology data that spans several drawing files (such as tiled maps) unless they are combined in a project.
AcMapTopologyAcMapTopologyManager
Prior to creating a new topology with Create(), call the following functions to override the default centroid-, edge-, and node-creation settings:
For topology source-code samples, see Topology Samples.
// Create a topology object, verify it, close it, and destroy it. AcMap::EErrCode errCode; ETopologyType eType = ePoint; const char* pszTopologyName = "MyNodeTopology"; // For safety, usually add the existence test // if (AcMapTopologyManager::TopologyExists(pszTopologyName)){...} // before creating a new topology. AcMapTopology* pTopology = new AcMapTopology(pszTopologyName); // See <a href="#samples">Topology Samples</a> for sample code // that shows how to populate these arrays. AcDbObjectIdArray edgeObjIds; AcDbObjectIdArray nodeObjIds; AcDbObjectIdArray centroidObjIds; ... errCode = pTopology->Create(edgeObjIds, nodeObjIds, centroidObjIds, int(eType)); if(AcMap::kOk == errCode) {} else {// Verify the result by closing and reopening the newly created topology. pTopology->Close(); pTopology->Open(AcMapTopology::eForRead); // Another test: Confirm that the topology has the correct nodes. AcMapNodePtrArray apNodes; if (AcMap::kOk == pTopology->GetNodes(apNodes)) {} else { // Cannot get nodes - handle the error. }// Verify the nodes.... apNodes.Empty();} // Clean up. pTopology->Close(); delete pTopology; pTopology = NULL;// Cannot create topology - handle the error.
AcMapTopologyAcMapTopologyManagerAcMapTopologySource
Note GetTopologySource() takes topology source information as AcMapTopologySource instances in the array typedef AcArray< AcMapTopologySource > AcMapTopologySourceArray.
For topology source-code samples, see Topology Samples.
// Rename a topology. AcMap::EErrCode errCode; const char* pszTopologyName = "MyTopology"; const char* pszNewTopologyName = "MyRenamedTopology"; errCode = AcMapTopologyManager::Rename(pszTopologyName, pszNewTopologyName); if (AcMap::kOk == errCode) {} else if (AcMap::kErrTopInvalidName == errCode) {// Process the renamed topology. // Perhaps inspect and change its description. ...} else if (AcMap::kErrTopNotExist == errCode) {// Handle the bad topology name. A bad name typically is // NULL, empty, too long, or has nonalphabetic characters.} else {// The given topology doesn't exist.}// Handle a different type of error.
AcMapTopologyAcMapTopoFullEdgeAcMapTopoNodeAcMapTopoPolygon
For topology source-code samples, see Topology Samples.
// Move a node in a topology. AcMap::EErrCode errCode; const char* pszTopologyName = "MyNodeTopology"; AcMapTopology* pTopology = new AcMapTopology(pszTopologyName); // Open the topology for write. if (AcMap::kOk == pTopology->Open(AcMapTopology::eForWrite)) {} else {// Get the node of interest (with object ID = 4, in this case) // and move it to a new location. AcMapTopoNode* pNode = NULL; pTopology->GetNode(pNode, 4); AcGePoint3d newLocation(39.0, 15.0, 0.0000); if (AcMap::kOk != pTopology->MoveNode(*pNode, newLocation)) {} delete pNode; pTopology->Close();// Handle the error.}// Cannot open topology - handle the error.
AcMapTopologyAcMapTopoFullEdgeAcMapTopoNodeAcMapTopoPolygon
For topology source-code samples, see Topology Samples.
// Find a polygon in a topology. AcMap::EErrCode errCode; const char* pszTopologyName = "MyPolygonTopology"; AcMapTopology* pTopology= new AcMapTopology(pszTopologyName); // Open the topology from the source drawing for read. if (AcMap::kOk == pTopology->Open(AcMapTopology::eForRead, true, false, NULL)) {} else {// Find the polygon containing a specific point. AcMapTopoPolygon* pPolygon; AcGePoint3d point(30.0, 12.0, 0.0000); errCode = pTopology->FindPolygon(pPolygon, point); if (AcMap::kOk == errCode) {} else {// Is this a polygon of interest (with object ID = 184, in this case)? if (pPolygon->GetID() == 184) {}// Process the polygon.} // Clean up. delete pPolygon; pPolygon = NULL; pTopology->Close();// FindPolygon() failed - handle the error.}// Failed to open topology - handle the error.
AcMapTopologyAcMapTopoFullEdgeAcMapTopoHalfEdgeAcMapTopoNodeAcMapTopoPolygon
For topology source-code samples, see Topology Samples.
// Get the nodes of a topology. AcMap::EErrCode errCode; const char* pszTopologyName = "MyNodeTopology"; AcMapTopology* pTopology = new AcMapTopology(pszTopologyName); AcMapNodePtrArray apNodes; // Open the topology for read. if (AcMap::kOk != pTopology->Open(AcMapTopology::eForRead, true, false, NULL)) {} if (Acad::eOk == pTopology->GetNodes(apNodes)) {// Failed to open topology - handle the error.} else {// Process each node. for (int i = 0; i < apNodes.length(); i++) {}// Get the node location. AcGePoint3d point; errCode = apNodes[i]->GetLocation(point); if(Acad::eOk == errCode) {}// Process the node.} // Clean up. apNodes.Empty(); pTopology->Close();// GetNodes() failed - handle the error.
For topology source-code samples, see Topology Samples.
// Get a specific polygon from a topology and print // statistics for its rings. AcMap::EErrCode errCode; char* pszTopologyName = "MyTopology"; AcMapTopology* pMapTopology = NULL; // Open the topology for read. if (AcMapTopologyManager::TopologyExists(pszTopologyName)) {} // Get a polygon of interest (with object ID = 10, in this case) // and retrieve its rings with GetBoundary(). AcMapTopoPolygon* pPolygon = NULL; if (AcMap::kOk == pTopology->GetPolygon(pPolygon, 10)) {pMapTopology = new AcMapTopology(pszTopologyName); if(AcMap::kOk != pMapTopology->Open(AcMapTopology::eForRead)) { // Cannot open topology - handle the error. }} else {// Get the polygon's rings. AcMapRingPtrArray apRings; errCode = pPolygon->GetBoundary(apRings); if (AcMap::kOk == errCode) {} else {// Get statistics for each ring. int nRings = apRings.length(); // Number of rings. for (int nRingIndex = 0; nRingIndex < nRings; nRingIndex++) {} apRings.Empty(); // Free the array of rings.AcMapTopoRing* pRing = apRings[nRingIndex]; // Is ring exterior or interior?. char* pszExtOrInt = pRing->IsExterior() ? "exterior" : "interior"; // Print the rings' area and length. acutPrintf("\n#%d is %10s, Area: %-0.4lf Length: %-0.4lf", (nRingIndex + 1), pszExtOrInt, pRing->GetArea(), pRing->GetLength());}// Cannot get the polygon's boundary - handle the error.} // Clean up. delete pPolygon; pPolygon = NULL; pMapTopology->Close();// Cannot get the specified polygon - handle the error.
<a id="analyzing">Analyzing Topologies
Note Before creating new topologies by buffering or overlaying existing topologies, you can call SetCentroidCreationSettings(), SetEdgeCreationSettings(), and SetNodeCreationSettings() to override the default topology-creation values.
For topology source-code samples, see Topology Samples.
// Two topologies are needed: source and overlay. const char* pszSourceTopologyName = "MyNodeTopology"; AcMapTopology* pSourceTopology = new AcMapTopology(pszSourceTopologyName); const char* pszOverlayTopologyName = "MyPolygonTopology"; AcMapTopology* pOverlayTopology = new AcMapTopology(pszOverlayTopologyName); AcMap::EErrCode errCode; // Open both source and overlay topologies for read. if(AcMap::kOk == pSourceTopology->Open(AcMapTopology::eForRead)) {} else {if(AcMap::kOk == pOverlayTopology->Open(AcMapTopology::eForRead)) {else {// Create the intersection of the source and overlay topologies. errCode = pSourceTopology->Intersect(pOverlayTopology, "OutputTopo", "Intersect", NULL, NULL, NULL); if(AcMap::kOk == errCode) {}// Process the topology intersection.} pOverlayTopology->Close();// Cannot create topology intersection - handle the error.} pSourceTopology->Close(); } else {// Cannot open overlay topology - handle the error.}// Cannot open source topology - handle the error.
AcMapTopoIteratorAcMapTopology
For topology source-code samples, see Topology Samples.
AcMap::EErrCode errCode; // Initialize the iterator. AcMapTopoIterator* pIterator = new AcMapTopoIterator; AcMapTopology* pTopology = NULL; // Iterate through the topology objects. pIterator->First(); while (!pIterator->IsDone()) {} delete pIterator; delete pTopology; // To iterate with a for-loop: // for (pIterator.First(); !pIterator.IsDone(); pIterator.Next()) {...}pIterator->GetTopology(pTopology); // Process the topology... errCode = pIterator->Next();
| Array class | Holds pointers to |
|---|---|
| AcMapFullEdgePtrArray | AcMapTopoFullEdge instances |
| AcMapHalfEdgePtrArray | AcMapTopoHalfEdge instances |
| AcMapNodePtrArray | AcMapTopoNode instances |
| AcMapObjectPtrArray | AcMapTopoElement instances |
| AcMapPolygonPtrArray | AcMapTopoPolygon instances |
| AcMapRingPtrArray | AcMapTopoRing instances |
For topology source-code samples, see Topology Samples.
Many functions in the various topology classes return an AcMap::EErrCode error code. When a particular function returns an error code, read that function's documentation for function-specific error conditions rather than relying on only the generic error descriptions in the AcMap::EErrCode documentation.
To view the topology classes, namespaces, and globals, click the following links:
AcMapEntityCreationSettings Class
AcMapPointCreationSettings Class
AcMapNetAnalysisParameters Class
AcMapTopoElementPtrArray Template Class
AcMapTopologyManager Namespace
AcMapObjectDataField Global Struct