概化数据涉及许多重复的劳动密集型任务,因此,将其实现自动化是一种理想的选择。然而,制图综合的关联性和主观性使其难以实现自动化。人脑非常善于考虑事情的先后顺序并同时根据情境做出调整。而通过一系列离散命令指示计算机执行此操作则会困难得多。
ArcGIS 中的地理处理环境非常适于建立制图综合框架,因为其能够按照特定于数据、比例和产品的变量指示的独立步骤来管理数据的变换。这些独立步骤可根据逻辑链接在一起,甚至在脚本或模型中形成循环,创建可应用于一系列数据的复杂工作流,从而生成用于打印或屏幕显示的多比例数据库。由此可以轻松地在不同的要素组上或以多种方式组合的不同参数按顺序重复任务。可以自动处理完整工作流,或者通过手动编辑过程中或编辑期间进行的验证将其细分成更小的工作流。
将制图综合任务合并到制图工作流
如果要制作其比例小于预期数据比例的地图,首先要了解目标比例、显示规范(包括符号系统)和地图的根本目的或意图。然后,执行相应操作,在不影响数据集的连通性或特征的情况下减少要素的总个数。接下来,通过移除折点或其他要素细节减少各要素的复杂性。其中也可能包括通过将相似的要显示的要素子类和相同的符号进行合并,来简化要素属性的复杂性。开始地图创建后,数据以其最终比例的最终符号系统显示,图形冲突可得到检测和解决。
以下流程图显示的是简化版本的制图综合工作流,并标识了制图工具箱中可支持概化数据以较小比例显示的一些关键工具。
大多数地理处理工具通常都能生成新的输出数据,然后这些输出数据可用作后续工具的输入,了解这一点非常重要。比较而言,制图人员通常遵循一种特定的工作流,该工作流通过逐渐改进已在地图文档中创建的要素图层进行表征。符号系统、图层属性和掩膜关系已经定义,因此最好在冲突解决和制图综合操作执行期间修改输入图层,以免丢失相关信息。因此,“制图”工具箱中的一些工具可修改符号化图层中的输入数据,而不创建数据。
在 ModelBuilder 中链接制图综合工具
制图综合工具使用多值输入,即一个或多个要素类的列表。许多地理处理工具接受多值(例如联合工具),但是制图综合工具却有点不同,它们还输出多值。您需要了解一些 ModelBuilder 技术以生成想要的模型。下面将对这些技术进行讨论。
链接具有多个输入和输出的工具
稀疏化道路网、解决道路冲突和解决建筑物冲突工具可输出多值。这意味着只有接受多值输入的工具才能直接使用这些工具的输出。例如,如果将三个图层用作稀疏化道路网工具的输入,且您想要在三个图层被稀疏化之后再将其用作解决道路冲突工具的输入,则您可以将稀疏化道路网工具的输出结果与解决道路冲突工具直接相连接。
可以使用收集值工具将更多图层添加到多值。以下例子展示了向稀疏化道路网中额外添加两个图层以创建解决道路冲突输入的过程。
将多个输出链接至单个输入
要将有多值输出的工具链接至接受单个输入的工具,请使用追加工具将多个要素类合并到一起。此工作流的一个示例是通过追加工具将稀疏化道路网工具处理的多个道路输入图层的结果进行合并,然后作为合并分开的道路工具的输入,该工具仅接受单个输入。
分别链接多个输入
在某些情况下,希望将工具中的多个输出分别传递到其他工具。如果您不希望第一个工具的所有输出参与第二个工具,或者如果您希望为第二个工具中的每个输入设置特定的参数,就会出现这种情形。例如,解决建筑物冲突工具允许完全控制将各输入图层定义为障碍的方式。在这些情况下,使用相同的一组图层同时作为两个工具的输入,但是将第一个工具的输出设置为第二个工具的前提条件来强制处理的正确顺序,如下图所示。此方法仅在第一种工具(如解决道路冲突工具)修改输入图层而不是创建新的输出图层时才适用。
了解有关在 ModelBuilder 中使用前提条件的详细信息
在以下示例中,三个交通图层同时用作两个工具的输入。这是可行的,因为这些图层由解决道路冲突工具修改,并且不创建新的输出要素类。解决道路冲突工具的输出用作解决建筑物冲突工具进行处理的前提条件,以确保解决道路冲突工具在解决建筑物冲突工具开始前完成处理。
符号化输入
要链接仅接受符号化图层的工具,需要使用创建要素图层工具和应用图层的符号系统工具为在 ModelBuilder 和脚本环境中进行链接准备输出图层。
为小比例显示准备数据的 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.MakeFeatureLayer_management("streamnetwork", "streamlayer", "", "", "")
# A selection is made for features which are rivers/streams
arcpy.SelectLayerByAttribute_management("streamlayer", "NEW_SELECTION",
'"FCsubtype" = 1')
# In order to reduce the complexity from the streams, vertices are removed using
# the Simplify Line tool
arcpy.SimplifyLine_cartography("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.SmoothLine_cartography("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.MakeFeatureLayer_management("streams", "streamslayer", "", "", "")
# Dashed line symbology from an existing layer is applied to the new streams
# feature layer
arcpy.ApplySymbologyFromLayer_management("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.SetControlPointByAngle_cartography("streamslayer", "130")
# Polygonal hydrographic features
# A selection is made to create a new feature class for reservoirs.
arcpy.Select_analysis("openwater", "reservoirs", '"FCsubtype" = 4')
# A selection is made to create a separate feature class for processing in order
# to generate lakes.
arcpy.Select_analysis("openwater", "water_select", '"FCsubtype" <> 4')
# In order to reduce the complexity from the lakes, vertices are removed using
# the Simplify Line tool.
arcpy.SimplifyPolygon_cartography("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.SmoothPolygon_cartography("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.SimplifyLine_cartography("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.MakeFeatureLayer_management("rail_simplified", "railwaylayer", "", "", "")
# Apply the symbology from an existing layer
arcpy.ApplySymbologyFromLayer_management("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.MergeDividedRoads_cartography("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.MakeFeatureLayer_management("railways", "railwayslayer", "", "", "")
# Pre-made railway symbology from an existing layer is applied to the
# new railway feature layer.
arcpy.ApplySymbologyFromLayer_management("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.SetControlPointByAngle_cartography("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.EliminatePolygonPart_management("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.SetControlPointAtIntersect_cartography("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.CalculateLineCaps_cartography("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.ThinRoadNetwork_cartography("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.MergeDividedRoads_cartography("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.MakeFeatureLayer_management("roads", "roadslayer", "", "", "")
# Pre-made symbology from an existing layer is applied to the roads feature
# layer.
arcpy.ApplySymbologyFromLayer_management("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.ResolveRoadConflicts_cartography
("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.SetControlPointByAngle_cartography("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.CreateOverpass_cartography("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.CreateUnderpass_cartography("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.PropagateDisplacement_cartography("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.MakeFeatureLayer_management("point_bldg", "bldglayer", "", "", "")
# Symbology is applied from an existing layer.
arcpy.ApplySymbologyFromLayer_management("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.AlignMarkerToStrokeOrFill_cartography("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.PropagateDisplacement_cartography("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.Select_analysis("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.AggregatePolygons_cartography("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.SimplifyBuilding_cartography("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.MakeFeatureLayer_management("area_bldg", "footprintlayer", "", "", "")
# Pre-made symbology is applied from an existing layer.
arcpy.ApplySymbologyFromLayer_management("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.ResolveBuildingConflicts_cartography("footprintlayer; bldglayer", "invisible",
"'roadslayer' 'true' '5 meters';'streamslayer' 'false' '5 meters';'railwayslayer' 'false' '10 meters'",
"10 meters", "20 meters", "level")