Skip to main content

通过地理处理自动化冲突解决和制图综合的工作流

概化数据包括许多重复的劳动密集型任务,因此它是自动化的理想候选项。 然而,概化的关联性和主观性使其难以实现自动化。 人脑善于优先处理和同时进行上下文让步。 而通过一系列离散命令指示计算机执行此操作则会困难得多。

ArcGIS 中的地理处理环境非常适合建立制图综合框架,原因是它可以按不同的隔离步骤(由数据、比例和产品特定变量定向)管理数据的转换。 这些步骤可以以逻辑的方式链接在一起,甚至可以在脚本或模型中循环以创建复杂的工作流,该工作流可以应用于一系列数据,以生成用于打印或屏幕显示的多比例数据库。 可以轻松地在不同的要素组上按顺序重复执行任务,也可以轻松地以各种方式组合不同的参数。 可以自动处理完整工作流,或者通过手动编辑过程中或编辑期间进行的验证将其细分成更小的工作流。

将制图综合任务合并到制图工作流

以比拟定数据小的比例制作地图的过程始于对目标比例的理解、显示规范(包括符号系统)以及地图的基本目的或意图。 接下来,执行操作以减少要素总数,而不影响数据集的连接性或特性。 通过移除折点或其他要素细节减少各要素的复杂性。 这也可以包括通过组合用于显示的具有相同符号的相似要素子类别来简化要素属性内的复杂性。 开始地图创建后,数据以其最终比例的最终符号系统显示,图形冲突可得到检测和解决。

以下流程图显示的是简化版本的制图综合工作流,并标识了 制图工具箱 中可支持概化数据以较小比例显示的一些关键工具。

制图综合工作流逻辑示意图

将显示用于概化制图显示数据的过程和相应地理处理工具的简化视图。

大多数地理处理工具通常会生成新数据作为输出,并且其可用作后续工作的输入,了解这一点至关重要。 与此相反,制图师通常执行的工作流的特征是对在地图文档中已建立的要素图层进行增量改进。 已定义符号系统、图层属性和掩膜关系,因此在执行冲突解决方案和制图综合操作时最好修改输入图层,以免丢失此信息。 因此,“制图”工具箱中的一些工具可修改符号化图层中的输入数据,而不创建数据。

在 模型构建器 中链接制图综合工具

制图综合工具使用多值输入,即一个或多个要素类的列表。 许多地理处理工具接受多值(例如 联合 工具),但是制图综合工具却不同,它们还输出多值。 您需要了解一些 模型构建器 技术以生成想要的模型。 下面将对这些技术进行讨论。

链接具有多个输入和输出的工具

稀疏化道路网解决道路冲突解决建筑物冲突 工具可输出多值。 这意味着只有接受多值输入的工具才能直接使用这些工具的输出。 例如,如果将三个图层用作 稀疏化道路网 工具的输入,且您想要在三个图层被稀疏化之后再将其用作 解决道路冲突 工具的输入,则您可以将 稀疏化道路网 工具的输出结果与 解决道路冲突 工具直接相连接。

包括多个制图综合输入的模型

通过“稀疏化道路网”工具连接到“解决道路冲突”工具的多个输入。

可以使用 收集值 工具将更多图层添加到多值。 以下例子展示了向 稀疏化道路网 中额外添加两个图层以创建 解决道路冲突 输入的过程。

使用“收集值”工具的模型

此模型“收集值”工具向“稀疏化道路网”工具的多值输出中添加更多输入,以便之后连接到“解决道路冲突”工具中。

将多个输出链接至单个输入

要将有多值输出的工具链接至接受单个输入的工具,请使用 追加 工具合并多个要素类。 此工作流的一个示例是通过追加工具将 稀疏化道路网 工具处理的多个道路输入图层的结果进行合并,然后作为 合并分开的道路 工具的输入,该工具仅接受单个输入。

使用“追加”工具的模型

此模型使用“追加”工具将多个输出合并到单个输入。

分别链接多个输入

在某些情况下,您希望将一个工具的多个输出分别传递给另一个工具。 如果您不希望第一个工具的所有输出都参与第二个工具,或者您想要为第二个工具中的每个输入设置特定参数,就会是这种情况。 例如, 解决建筑物冲突 工具允许完全控制将各输入图层定义为障碍的方式。 在这些情况下,使用相同的图层集作为两个工具的输入,但是将第一个工具的输出设置为第二个工具的前提条件,以强制执行正确的处理顺序,如下所示。 此方法仅在第一种工具(如 解决道路冲突 工具)修改输入图层而不是创建新的输出图层时才适用。

了解有关在 模型构建器 中使用前提条件的详细信息

在下面的示例中,三个运输层用作这两个工具的输入。 这是可行的,因为这些图层由 解决道路冲突 工具修改,并且不创建新的输出要素类。 解决道路冲突 工具的输出用作 解决建筑物冲突 工具进行处理的前提条件,以确保 解决道路冲突 工具在 解决建筑物冲突 工具开始前完成处理。

使用前提条件的模型

将“解决道路冲突”工具的输出用作“解决建筑物冲突”工具的前提条件,以强制处理顺序。

符号化输入

要链接仅接受符号化图层的工具,需要使用 创建要素图层 工具和 应用图层的符号系统 工具为在 模型构建器 和脚本环境中进行链接准备输出图层。

将符号图层用作输入的模型

使用“创建要素图层”工具和“应用图层的符号系统”工具在工具之间传递符号信息。

为小比例显示准备数据的 Python 脚本示例

制图工具箱工作流示例(独立脚本)

此独立脚本完成一个示例工作流,方法是使用“制图”工具箱中的多个工具概化 1:25,000 比例的数据,并解决以 1:50,000 比例下显示时的图形冲突。

# Name: cartography_workflow_script.py
# Description: Process features in order to resolve graphic conflicts when
# changing scales from 25K to 50K.
#
# Tools used = Aggregate Polygons, Align Marker To Stroke Or Fill, Apply
#              Symbology From Layer, Create Overpass, Create Underpass, Calculate
#              Line Caps, Eliminate Polygon Part, Make Feature Layer, Merge
#              Divided Roads, Propagate Displacement, Resolve Building Conflicts
#              Resolve Road Conflicts, Select, Select Layer By Attribute, Set
#              Control Point At Intersect, Set Control Point By Angle, Simplify
#              Building, Simplify Line, Simplify Polygon, Smooth Line, Smooth
#              Polygon, Thin Road Network
# Minimum ArcGIS Pro version = 2.1
#
# The geodatabase used in this workflow is assumed to be in c:\data
# - please replace this path to your machine specific folder.

# Import system modules
import arcpy

# Start the processing
arcpy.env.workspace = "C:/data/cartography.gdb"

# The data was captured at a scale of 1:24000, and this workflow will produce
# data appropriate for a scale of 1:50000.
# Most of the geoprocessing tools in this workflow require a reference scale
arcpy.env.referenceScale = "50000"
arcpy.env.cartographicCoordinateSystem = ""

###############
# HYDROGRAPHY #
###############

# A subset of linear features (rivers/streams) will be processed
# for simplification and smoothing
# A subset of polygonal features (reservoirs/lakes) will be processed
# for simplification and smoothing

# The workspace is set to the hydrography feature dataset
arcpy.env.workspace = "C:/data/cartography.gdb/hydrography"

# Linear hydrographic features
arcpy.management.MakeFeatureLayer("streamnetwork", "streamlayer", "", "", "")

# A selection is made for features which are rivers/streams
arcpy.management.SelectLayerByAttribute("streamlayer", "NEW_SELECTION",
                                     '"FCsubtype" = 1')

# In order to reduce the complexity from the streams, vertices are removed using
# the Simplify Line tool
arcpy.cartography.SimplifyLine("streamlayer", "streams_simplified",
                            "BEND_SIMPLIFY", "100 meters", "RESOLVE_ERRORS")

# In order to reduce the amount or severity of sharp angles, Smooth Line is used
# to improve the shape of the streams
arcpy.cartography.SmoothLine("streams_simplified", "streams",
                          "BEZIER_INTERPOLATION", "#", "0", 'FLAG_ERRORS')

# Some of the processed features are intermittent rivers or streams and are
# symbolized as dashed lines. The dashes can be centered around corners to
# improve the look of the features. The corners are identified as vertices which
# will be flagged as control points. Symbology from an existing layer containing
# dashed line symbols is then applied.

# A new feature layer is created from the streams data to be used as input
# when setting control points.
arcpy.management.MakeFeatureLayer("streams", "streamslayer", "", "", "")

# Dashed line symbology from an existing layer is applied to the new streams
# feature layer
arcpy.management.ApplySymbologyFromLayer("streamslayer",
                                      "C:/data/stream_symbols.lyrx")

# The dashes in the stream symbol will be placed at control points created
# anywhere an angle is less than (or equal to) 130 degrees.
arcpy.cartography.SetControlPointByAngle("streamslayer", "130")

# Polygonal hydrographic features
# A selection is made to create a new feature class for reservoirs.
arcpy.analysis.Select("openwater", "reservoirs", '"FCsubtype" = 4')

# A selection is made to create a separate feature class for processing in order
# to generate lakes.
arcpy.analysis.Select("openwater", "water_select", '"FCsubtype" <> 4')

# In order to reduce the complexity from the lakes, vertices are removed using
# the Simplify Line tool.
arcpy.cartography.SimplifyPolygon("water_select", "water_simplified",
                               "BEND_SIMPLIFY", "100 meters", "0",
                               "RESOLVE_ERRORS")

# In order to reduce the amount (or severity) of sharp angles, Smooth Line is
# used to improve the shape of the lakes.
arcpy.cartography.SmoothPolygon("water_simplified", "lakes",
                             "BEZIER_INTERPOLATION", "0", "", "FLAG_ERRORS")

#############
# RAILROADS #
#############

# Set the workspace to the transportation feature dataset
arcpy.env.workspace = "C:/data/cartography.gdb/transportation"
# In order to reduce the complexity from the railroads, vertices are removed
# using the Simplify Line tool.
arcpy.cartography.SimplifyLine("railnetwork", "rail_simplified",
                            "BEND_SIMPLIFY", "100 meters", "RESOLVE_ERRORS")

# The Merge Divided Roads tool requires symbolized features, so a feature layer
# is created using the simplified rail features, and then pre-made symbology is
# applied from an existing feature layer.

# A feature layer is created from the simplified rail features.
arcpy.management.MakeFeatureLayer("rail_simplified", "railwaylayer", "", "", "")

# Apply the symbology from an existing layer
arcpy.management.ApplySymbologyFromLayer("railwaylayer",
                                      "C:/data/rail_symbols.lyrx")

# The Merge Divided Roads tool will be used to generates single line railroad
# features in place of multiple divided railroad lanes.
arcpy.cartography.MergeDividedRoads("railwaylayer", "level", "25 Meters",
                                 "railways")

# Symbolized features are required when adding control points, so a new feature
# layer is created from the output of the MergeDivvidedRoads tool.
arcpy.management.MakeFeatureLayer("railways", "railwayslayer", "", "", "")

# Pre-made railway symbology from an existing layer is applied to the
# new railway feature layer.
arcpy.management.ApplySymbologyFromLayer("railwayslayer",
                                      "C:/data/rail_symbols.lyrx")

# The tick marks in railroad symbol (markers) will be placed at control points
# created anywhere an angle is less than (or equal to) 130 degrees.
arcpy.cartography.SetControlPointByAngle("railwayslayer", "130")

###########
# LANDUSE #
###########

# Set the workspace to the landuse feature dataset
arcpy.env.workspace = "C:/data/cartography.gdb/landuse"
# The polygons which represent landcover have holes in them where buildings are
# located. The holes need to be removed so they will not appear after buildings
# have moved. In this example, any hole which is less than 50 percent of the
# feature's area will be removed.
arcpy.management.EliminatePolygonPart("cultural", "urban_area", "PERCENT", "0",
                                   "50", "CONTAINED_ONLY")

##############
# BOUNDARIES #
##############

# The boundary features have dashed outlines which are not in phase with each
# other on shared edges between features. To make the dashed outlines in phase
# with each other, control points are added wherever features
# share coincident vertices.
arcpy.cartography.SetControlPointAtIntersect("C:/data/boundaries.lyrx",
                                          "C:/data/boundaries.lyrx")

#########
# ROADS #
#########

# Set the workspace to the transportation feature dataset
arcpy.env.workspace = "C:/data/cartography.gdb/transportation"
# Linear features

# Roads which are dead ends (or cul-de-sacs) should have their Line ending
# property set to BUTT.
arcpy.cartography.CalculateLineCaps("C:/data/road_symbols.lyrx", "BUTT",
                                 "CASED_LINE_DANGLE")

# Thin Road Network identifies a subset of road segments that can be removed from
# the display to create a simplified road network that retains the connectivity
# and general character of the input collection. Features are flagged for removal
# when their attribute value in the "invisible" field equals one. A layer
# definition query can be used to display the resulting simplified feature class.
arcpy.cartography.ThinRoadNetwork("roadnetwork", "500 meters", "invisible",
                               "level")

# The Merge Divided Roads tool will be used to generates single line road
# features in place of multiple divided road lanes.
arcpy.cartography.MergeDividedRoads("C:/data/road_symbols.lyrx", "level",
                                 "25 meters", "roads")

# The Resolve Road Conflicts tool requires symbolized features, so a feature
# layer is created from the roads features so that pre-made
# symbology can the be applied to the new roads feature layer.
arcpy.management.MakeFeatureLayer("roads", "roadslayer", "", "", "")

# Pre-made symbology from an existing layer is applied to the roads feature
# layer.
arcpy.management.ApplySymbologyFromLayer("roadslayer",
                                      "C:/data/road_symbols.lyrx")

# The Resolve Road Conflicts tool does not produce output road layers but instead
# alters the source feature classes of the input road layers. The Resolve Road
# Conflicts tool adjusts line features to ensure that they are graphically
# distinguishable when symbolized at output scale.
arcpy.cartography.ResolveRoadConflicts("roadslayer",
                                                "level",
                                                "C:/data/cartography.gdb/buildings/displacement")

# The dashes in the road symbols will be placed at control points created
# anywhere an angle is less than (or equal to) 130 degrees.
arcpy.cartography.SetControlPointByAngle("roadslayer", "130")

# Create bridges
# The Create Overpass tool will create a bridge for the roads and a mask for the
# streams wherever a road goes over a steam.
arcpy.cartography.CreateOverpass("roadslayer", "streamslayer", "2 points",
                              "1 points", "over_mask_fc", "over_mask_rc",
                              '"BridgeCategory" = 1', "bridges",
                              "ANGLED", "1 points")

# Create tunnels
# The Create Overpass tool will create a tunnel for the railroads and a mask for
# the railroads wherever a railroad goes under a road.
arcpy.cartography.CreateUnderpass("roadslayer", "railwayslayer", "2 points",
                               "1 points", "under_mask_fc", "under_mask_rc",
                               '"RelationshipToSurface" = 3', "tunnels",
                               "ANGLED", "1 points")

#############
# BUILDINGS #
#############

# Set the workspace to the buildings feature dataset
arcpy.env.workspace = "C:/data/cartography.gdb/buildings"
# Point features

# When the road features were adjusted by the Resolve Road Conflicts tool, the
# spatial relationship with nearby buildings was affected. A displacement feature
# class was created by that tool in order to record the change applied to the
# roads. This information can be used by the Propagate Displacement tool to apply
# the same change to the point buildings.

# The road displacement is propagated to the point buildings
arcpy.cartography.PropagateDisplacement("point_bldg", "displacement", "AUTO")

# Point buildings will be rotated against nearby linear roads
# The Align Markers To Stroke Or Fill tool can do this with symbolized features.

# A feature layer is made for point buildings
arcpy.management.MakeFeatureLayer("point_bldg", "bldglayer", "", "", "")

# Symbology is applied from an existing layer.
arcpy.management.ApplySymbologyFromLayer("bldglayer",
                                      "C:/data/bldg_symbols.lyrx")

# The Align Marker to Stroke Or Fill tool is used to align point buildings to
# face road features within 5 points of the buildings
arcpy.cartography.AlignMarkerToStrokeOrFill("bldglayer", "roadslayer",
                                         "5 points", "PERPENDICULAR")

# Polgyonal features
# When the road features were adjusted by the Resolve Road Conflicts tool, the
# spatial relationship with nearby buildings was affected. A displacement
# feature class was created by that tool in order to record the change applied
# to the roads. This information can be used by the Propagate Displacement tool
# to apply the same change to the polygonal buildings.

# The road displacement is propagated to polygon buildings
arcpy.cartography.PropagateDisplacement("footprints", "displacement", "SOLID")

# A selection is made to create a feature class with buildings larger than
# a minimum size
# The small buildings are not appropriate at the new map scale of 1:50,000
arcpy.analysis.Select("footprints", "buildings_select", '"Shape_Area" > 100')

# There is a need to create better spacing between polygon buildings and combine
# them when they share edges or are very close together
# The Aggregate Polygons tool is used to accomplish this task
arcpy.cartography.AggregatePolygons("buildings_select", "large_buildings",
                                 "20 meters", "", "", "ORTHOGONAL")

# In order to reduce the complexity of the buildings, indentations, extensions
# and extra vertices are removed using the Simplify Building tool.
# Buildings require less visible detail at the new scale of 1:50,000.
arcpy.cartography.SimplifyBuilding("large_buildings", "area_bldg", "20 meters",
                                "0 unknown", "CHECK_CONFLICTS")

# All buildings require further improvements to achieve better spacing between
# themselves and other nearby features. At the new scale of 1:50,000 the
# symbolized buildings may overlap other features and create a visually congested
# map. To improve the visual congestion, the Resolve Building Conflicts tool is
# used. Buildings are improved in the context of their surrounding features.
# These features are considered barriers to buildings. The Resolve Building
# Conflicts tool requires symbolized features and has several options available
# to improve the buildings. Options include: moving or resizing the buildings,
# orienting or snapping the buildings to nearby features, as well as making the
# buildings invisible. Buildings from multiple feature classes can be used as
# inputs to the tool. Barriers from multiple feature classes can be used as
# inputs to the tool. For each barrier, the option is available to specify a snap
# or orient action for the buildings when they are within a specified distance.
# For each barrier, the option is available to specify a minimum distance for
# buildings to maintain between them.

# A feature layer is made for the polygon buildings
arcpy.management.MakeFeatureLayer("area_bldg", "footprintlayer", "", "", "")

# Pre-made symbology is applied from an existing layer.
arcpy.management.ApplySymbologyFromLayer("footprintlayer",
                                      "C:/data/footprint_symbols.lyrx")

# The Resolve Building Conflicts tool is run with point and polygon buildings
# against roads, streams and railroads. The buildings will be moved away from
# streams and railroads until they reach a minimum distance. The buildings
# within a maximum distance from the roads will be rotated. Further movement
# and rotation may still be required by the tool in order to resolve any
# remaining graphic conflict.
arcpy.cartography.ResolveBuildingConflicts("footprintlayer; bldglayer", "invisible",
                                        "'roadslayer' 'true' '5 meters';'streamslayer' 'false' '5 meters';'railwayslayer' 'false' '10 meters'",
                                        "10 meters", "20 meters", "level")