Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revise UtilityNetworkTrace API #864

Draft
wants to merge 2 commits into
base: v.next
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 2 additions & 15 deletions Examples/Examples/UtilityNetworkTraceExampleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,19 @@ struct UtilityNetworkTraceExampleView: View {
/// A container for graphical trace results.
@State private var resultGraphicsOverlay = GraphicsOverlay()

/// Provides the ability to detect tap locations in the context of the screen.
@State private var screenPoint: CGPoint?

/// The map viewpoint used by the `UtilityNetworkTrace` to pan/zoom the map to selected features.
@State private var viewpoint: Viewpoint?

var body: some View {
GeometryReader { geometryProxy in
MapViewReader { mapViewProxy in
MapView(
map: map,
viewpoint: viewpoint,
graphicsOverlays: [resultGraphicsOverlay]
)
.onAttributionBarHeightChanged {
attributionBarHeight = $0
}
.onSingleTapGesture { screenPoint, mapPoint in
self.screenPoint = screenPoint
.onSingleTapGesture { _, mapPoint in
self.mapPoint = mapPoint
}
.onViewpointChanged(kind: .centerAndScale) {
viewpoint = $0
}
.task {
let publicSample = try? await ArcGISCredential.publicSample
ArcGISEnvironment.authenticationManager.arcGISCredentialStore.add(publicSample!)
Expand All @@ -76,9 +65,7 @@ struct UtilityNetworkTraceExampleView: View {
graphicsOverlay: $resultGraphicsOverlay,
map: map,
mapPoint: $mapPoint,
screenPoint: $screenPoint,
mapViewProxy: mapViewProxy,
viewpoint: $viewpoint
mapViewProxy: mapViewProxy
)
.floatingPanelDetent($activeDetent)
// Manually account for a device's bottom safe area when using a Floating Panel.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,9 @@ public struct UtilityNetworkTrace: View {
/// The graphics overlay to hold generated starting point and trace graphics.
@Binding private var graphicsOverlay: GraphicsOverlay

/// Acts as the point of identification for items tapped in the utility network.
@Binding private var screenPoint: CGPoint?

/// Acts as the point at which newly selected starting point graphics will be created.
@Binding private var mapPoint: Point?

/// Allows the Utility Network Trace Tool to update the parent map view's viewpoint.
@Binding private var viewpoint: Viewpoint?

// MARK: Subviews

/// Allows the user to switch between the trace creation and viewing tabs.
Expand Down Expand Up @@ -199,8 +193,6 @@ public struct UtilityNetworkTrace: View {
let newViewpoint = Viewpoint(boundingGeometry: geometry.extent)
if let mapViewProxy {
Task { await mapViewProxy.setViewpoint(newViewpoint, duration: nil) }
} else {
viewpoint = newViewpoint
}
}
}
Expand Down Expand Up @@ -344,8 +336,14 @@ public struct UtilityNetworkTrace: View {
if await viewModel.trace() {
currentActivity = .viewingTraces(nil)
if shouldZoomOnTraceCompletion,
let extent = viewModel.selectedTrace?.resultExtent {
viewpoint = Viewpoint(boundingGeometry: extent)
let extent = viewModel.selectedTrace?.resultExtent,
let mapViewProxy {
Task {
await mapViewProxy.setViewpoint(
Viewpoint(boundingGeometry: extent),
duration: nil
)
}
}
}
}
Expand Down Expand Up @@ -389,8 +387,6 @@ public struct UtilityNetworkTrace: View {
let newViewpoint = Viewpoint(boundingGeometry: resultExtent)
if let mapViewProxy {
Task { await mapViewProxy.setViewpoint(newViewpoint, duration: nil) }
} else {
viewpoint = newViewpoint
}
}
}
Expand Down Expand Up @@ -524,8 +520,6 @@ public struct UtilityNetworkTrace: View {
let newViewpoint = Viewpoint(boundingGeometry: extent)
if let mapViewProxy {
Task { await mapViewProxy.setViewpoint(newViewpoint, duration: nil) }
} else {
viewpoint = newViewpoint
}
}
}
Expand Down Expand Up @@ -624,25 +618,19 @@ public struct UtilityNetworkTrace: View {
/// - graphicsOverlay: The graphics overlay to hold generated starting point and trace graphics.
/// - map: The map containing the utility network(s).
/// - mapPoint: Acts as the point at which newly selected starting point graphics will be created.
/// - screenPoint: Acts as the point of identification for items tapped in the utility network.
/// - mapViewProxy: The proxy to provide access to map view operations.
/// - viewpoint: Allows the utility network trace tool to update the parent map view's viewpoint.
/// - startingPoints: An optional list of programmatically provided starting points.
public init(
graphicsOverlay: Binding<GraphicsOverlay>,
map: Map,
mapPoint: Binding<Point?>,
screenPoint: Binding<CGPoint?>,
mapViewProxy: MapViewProxy?,
viewpoint: Binding<Viewpoint?>,
startingPoints: Binding<[UtilityNetworkTraceStartingPoint]> = .constant([])
) {
self.mapViewProxy = mapViewProxy
_activeDetent = .constant(nil)
_screenPoint = screenPoint
_mapPoint = mapPoint
_graphicsOverlay = graphicsOverlay
_viewpoint = viewpoint
_externalStartingPoints = startingPoints
_viewModel = StateObject(
wrappedValue: UtilityNetworkTraceViewModel(
Expand Down Expand Up @@ -694,18 +682,16 @@ public struct UtilityNetworkTrace: View {
}
.background(Color(uiColor: .systemGroupedBackground))
.animation(.default, value: currentActivity)
.onChange(of: screenPoint) { newScreenPoint in
.onChange(of: mapPoint) { newMapPoint in
guard isFocused(traceCreationActivity: .addingStartingPoints),
let mapViewProxy = mapViewProxy,
let mapPoint = mapPoint,
let screenPoint = newScreenPoint else {
let mapPoint = newMapPoint,
let mapViewProxy = mapViewProxy else {
return
}
currentActivity = .creatingTrace(.viewingStartingPoints)
activeDetent = .half
Task {
await viewModel.addStartingPoints(
at: screenPoint,
mapPoint: mapPoint,
with: mapViewProxy
)
Expand Down Expand Up @@ -1028,3 +1014,39 @@ private extension String {
)
}
}

public extension UtilityNetworkTrace /* Deprecated */ {
/// A graphical interface to run pre-configured traces on a map's utility networks.
/// - Parameters:
/// - graphicsOverlay: The graphics overlay to hold generated starting point and trace graphics.
/// - map: The map containing the utility network(s).
/// - mapPoint: Acts as the point at which newly selected starting point graphics will be created.
/// - screenPoint: Acts as the point of identification for items tapped in the utility network.
/// - mapViewProxy: The proxy to provide access to map view operations.
/// - viewpoint: Allows the utility network trace tool to update the parent map view's viewpoint.
/// - startingPoints: An optional list of programmatically provided starting points.
/// - Attention: Deprecated at 200.6.
@available(*, deprecated, message: "Use 'init(graphicsOverlay:map:mapPoint:mapViewProxy:startingPoints:)' instead.")
init(
graphicsOverlay: Binding<GraphicsOverlay>,
map: Map,
mapPoint: Binding<Point?>,
screenPoint: Binding<CGPoint?>,
mapViewProxy: MapViewProxy?,
viewpoint: Binding<Viewpoint?>,
startingPoints: Binding<[UtilityNetworkTraceStartingPoint]> = .constant([])
) {
self.mapViewProxy = mapViewProxy
_activeDetent = .constant(nil)
_mapPoint = mapPoint
_graphicsOverlay = graphicsOverlay
_externalStartingPoints = startingPoints
_viewModel = StateObject(
wrappedValue: UtilityNetworkTraceViewModel(
map: map,
graphicsOverlay: graphicsOverlay.wrappedValue,
startingPoints: startingPoints.wrappedValue
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,18 @@ import SwiftUI

/// Adds new starting points to the pending trace.
/// - Parameters:
/// - screenPoint: A point on the map in screen coordinates.
/// - mapPoint: A point on the map in map coordinates.
/// - proxy: Provides a method of layer identification.
///
/// An identify operation will run on each layer in the network. Every element returned from
/// each layer will be added as a new starting point.
func addStartingPoints(at screenPoint: CGPoint, mapPoint: Point, with proxy: MapViewProxy) async {
func addStartingPoints(mapPoint: Point, with proxy: MapViewProxy) async {
await withTaskGroup(of: Void.self) { [weak self] taskGroup in
guard let self else { return }
for layer in network?.layers ?? [] {
taskGroup.addTask { @MainActor in
if let result = try? await proxy.identify(on: layer, screenPoint: screenPoint, tolerance: 10) {
if let screenPoint = proxy.screenPoint(fromLocation: mapPoint),
let result = try? await proxy.identify(on: layer, screenPoint: screenPoint, tolerance: 10) {
for element in result.geoElements {
await self.processAndAdd(
startingPoint: UtilityNetworkTraceStartingPoint(geoElement: element, mapPoint: mapPoint)
Expand Down