Skip to content

Commit 2ae693c

Browse files
authored
Precipitations: Snow and Rain (#2360)
1 parent 34313b2 commit 2ae693c

File tree

17 files changed

+1235
-1
lines changed

17 files changed

+1235
-1
lines changed

Apps/Examples/Examples.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
F5E96E5798947CA56FD77CF9 /* Fire_Hydrants.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 02DA2CC04980F807255D646B /* Fire_Hydrants.geojson */; };
151151
F613749DCDDDDC6F041032A0 /* SimpleMapExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78811E5A3185D2D32495870A /* SimpleMapExample.swift */; };
152152
F6E3EF9BE4F1D2F58DE1BED2 /* radar1.gif in Resources */ = {isa = PBXBuildFile; fileRef = 8BD8BADE1108B0D380D9BEF8 /* radar1.gif */; };
153+
FA077DC5A6CF295906536DF1 /* PrecipitationsExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDBCA79855B58FE84333124 /* PrecipitationsExample.swift */; };
153154
FA53EEA88DB29D4D5AC58514 /* StandardInteractiveFeaturesExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FBAFDF929532EDB964786F4 /* StandardInteractiveFeaturesExample.swift */; };
154155
FDA4B57BE32D92BB57A5B7E6 /* FeaturesAtPointExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6239A5CDA61892902765B843 /* FeaturesAtPointExample.swift */; platformFilters = (ios, ); };
155156
/* End PBXBuildFile section */
@@ -287,6 +288,7 @@
287288
B33F64CDBA98B91EE819B2C4 /* AddMarkersSymbolExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMarkersSymbolExample.swift; sourceTree = "<group>"; };
288289
B7A7586D05B960928AB17A0D /* MultipleGeometriesExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipleGeometriesExample.swift; sourceTree = "<group>"; };
289290
BE18E37A8652B4807D2459F1 /* ExamplesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExamplesUITests.swift; sourceTree = "<group>"; };
291+
BFDBCA79855B58FE84333124 /* PrecipitationsExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrecipitationsExample.swift; sourceTree = "<group>"; };
290292
C0CC67084BA1191D0B179A94 /* PuckPlayground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PuckPlayground.swift; sourceTree = "<group>"; };
291293
C47942F80A50166AC823012B /* sportcar.glb */ = {isa = PBXFileReference; path = sportcar.glb; sourceTree = "<group>"; };
292294
C61CC711054A032EE0446036 /* DynamicStylingExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicStylingExample.swift; sourceTree = "<group>"; };
@@ -402,6 +404,7 @@
402404
DD3A816C6E4D7A0A532EEE84 /* GeofencingUserLocation.swift */,
403405
62DA0608D44DEF6C4A82777C /* LocateMeExample.swift */,
404406
45B39AE24486FED5ED30392D /* LocationOverrideExample.swift */,
407+
BFDBCA79855B58FE84333124 /* PrecipitationsExample.swift */,
405408
6CD7ADCCB774239AA0090C46 /* RasterParticleExample.swift */,
406409
AC5A8729C9AEA4711B56B5F0 /* SnapshotMapExample.swift */,
407410
E97E057D9FFB1DE3E16F1F0B /* StandardInteractiveBuildingsExample.swift */,
@@ -723,6 +726,7 @@
723726
mainGroup = AFDB1EA82615CFDF02CE1D4D;
724727
packageReferences = (
725728
B50D5CC28BF0DFBA55456D89 /* XCRemoteSwiftPackageReference "Fingertips" */,
729+
F97B927925CFCEE0B8496DE3 /* XCLocalSwiftPackageReference "../../" */,
726730
);
727731
projectDirPath = "";
728732
projectRoot = "";
@@ -904,6 +908,7 @@
904908
F48BF087BB56B0A44D8B16F3 /* PointAnnotationClusteringExample.swift in Sources */,
905909
4417BB8A356335BC8421A19B /* PointClusteringExample.swift in Sources */,
906910
6661DB69D4980E24BCA18AB2 /* PolygonAnnotationExample.swift in Sources */,
911+
FA077DC5A6CF295906536DF1 /* PrecipitationsExample.swift in Sources */,
907912
B304BACFCD08802A740E8919 /* PuckPlayground.swift in Sources */,
908913
0E191B29AE31584DCFDC3821 /* RasterColorExample.swift in Sources */,
909914
F492E2C8D35572B4CF48FE68 /* RasterParticleExample.swift in Sources */,
@@ -1339,6 +1344,13 @@
13391344
};
13401345
/* End XCRemoteSwiftPackageReference section */
13411346

1347+
/* Begin XCLocalSwiftPackageReference section */
1348+
F97B927925CFCEE0B8496DE3 /* XCLocalSwiftPackageReference "../../" */ = {
1349+
isa = XCLocalSwiftPackageReference;
1350+
relativePath = ../../;
1351+
};
1352+
/* End XCLocalSwiftPackageReference section */
1353+
13421354
/* Begin XCSwiftPackageProductDependency section */
13431355
0AF5F744C6369BF1FB233FB6 /* MapboxMaps */ = {
13441356
isa = XCSwiftPackageProductDependency;
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import SwiftUI
2+
@_spi(Experimental) import MapboxMaps
3+
4+
@available(iOS 14.0, *)
5+
struct PrecipitationExample: View {
6+
@State var viewport: Viewport = .camera(center: CLLocationCoordinate2D(latitude: 37.33464837343596, longitude: -122.00896178062911), zoom: 18, pitch: 80)
7+
8+
@State var snowState: PrecipitationState = .none
9+
@State var rainState: PrecipitationState = .none
10+
11+
enum PrecipitationState: CaseIterable {
12+
case none, light, medium, heavy
13+
14+
var intensity: Double {
15+
switch self {
16+
case .none: return 0
17+
case .light: return 0.2
18+
case .medium: return 0.6
19+
case .heavy: return 1.0
20+
}
21+
}
22+
23+
var opacity: Double {
24+
switch self {
25+
case .none: return 0
26+
case .light: return 0.3
27+
case .medium: return 0.5
28+
case .heavy: return 0.8
29+
}
30+
}
31+
32+
var snowIcon: String {
33+
switch self {
34+
case .none: return "snowflake"
35+
case .light: return "cloud.hail"
36+
case .medium: return "cloud.hail.fill"
37+
case .heavy: return "cloud.snow.fill"
38+
}
39+
}
40+
41+
var rainIcon: String {
42+
switch self {
43+
case .none: return "drop"
44+
case .light: return "cloud.drizzle"
45+
case .medium: return "cloud.drizzle.fill"
46+
case .heavy: return "cloud.rain.fill"
47+
}
48+
}
49+
50+
mutating func toggle() {
51+
let allCases = PrecipitationState.allCases
52+
let currentIndex = allCases.firstIndex(of: self)!
53+
let nextIndex = (currentIndex + 1) % allCases.count
54+
self = allCases[nextIndex]
55+
}
56+
}
57+
58+
var body: some View {
59+
Map(viewport: $viewport) {
60+
Puck2D(bearing: .heading)
61+
if snowState != .none {
62+
Snow()
63+
.intensity(snowState.intensity)
64+
.opacity(snowState.opacity)
65+
.vignette(0.5)
66+
}
67+
if rainState != .none {
68+
Rain()
69+
.intensity(rainState.intensity)
70+
.opacity(rainState.opacity)
71+
.vignette(0.2)
72+
.color(.blue.withAlphaComponent(0.4))
73+
}
74+
}
75+
.mapStyle(.standard)
76+
.ignoresSafeArea()
77+
.safeOverlay(alignment: .trailing) {
78+
VStack {
79+
Button {
80+
snowState.toggle()
81+
} label: {
82+
Image(systemName: snowState.snowIcon)
83+
}
84+
.buttonStyle(MapFloatingButtonStyle())
85+
Button {
86+
rainState.toggle()
87+
} label: {
88+
Image(systemName: rainState.rainIcon)
89+
}
90+
.buttonStyle(MapFloatingButtonStyle())
91+
}
92+
}
93+
}
94+
}
95+
96+
@available(iOS 14.0, *)
97+
struct PrecipitationExample_Preview: PreviewProvider {
98+
static var previews: some View {
99+
PrecipitationExample()
100+
}
101+
}

Apps/Examples/Examples/SwiftUI Examples/StandardStyleImportExample.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ struct StandardStyleImportExample: View {
101101
}
102102
}
103103

104-
@available (iOS 14.0, *)
104+
@available(iOS 14.0, *)
105105
private struct HotelCallout: View {
106106
var feature: FeaturesetFeature
107107

Apps/Examples/Examples/SwiftUI Examples/SwiftUIRoot.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct SwiftUIRoot: View {
5858
ExampleLink("Attribution dialog with presented sheet", destination: AttributionDialogueWithSheet())
5959
}
6060
#endif
61+
ExampleLink("Precipitation", note: "Show show and rain", destination: PrecipitationExample())
6162

6263
} header: { Text("Testing Examples") }
6364
}

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ That initializer doesn't require to wrap arguments in `Argument` cases. For exam
2020
* Add new experimental `radius` parameter to `TapInteraction`, `LongPressInteraction` and interaction managers to control the radius of a tappable area.
2121
* Add a way to specify image expression options.
2222
* Bump core maps version to 11.9.0-beta.1 and common sdk to 24.9.0-beta.1
23+
* Add new experimental APIs to control precipitation rendering. Snow and Rain are available now with an `@_spi(Experimental)` import prefix.
2324

2425
## 11.8.0 - 11 November, 2024
2526

Sources/MapboxMaps/ContentBuilders/MapContent/MapContentUniqueProperties.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ struct MapContentUniqueProperties: Decodable {
1313
var terrain: Terrain?
1414
var atmosphere: Atmosphere?
1515
var projection: StyleProjection?
16+
var snow: Snow?
17+
var rain: Rain?
1618
var transition: TransitionOptions?
1719
var location: LocationOptions?
1820
var lights = Lights()
@@ -38,6 +40,8 @@ struct MapContentUniqueProperties: Decodable {
3840
update("atmosphere", old: old.atmosphere, new: atmosphere, initial: initial?.atmosphere, setter: style.setStyleAtmosphereForProperties(_:))
3941
update("projection", old: old.projection, new: projection, initial: initial?.projection, setter: style.setStyleProjectionForProperties(_:))
4042
update("terrain", old: old.terrain, new: terrain, initial: initial?.terrain, setter: style.setStyleTerrainForProperties(_:))
43+
update("snow", old: old.snow, new: snow, initial: initial?.snow, setter: style.setStyleSnowForProperties(_:))
44+
update("rain", old: old.rain, new: rain, initial: initial?.rain, setter: style.setStyleRainForProperties(_:))
4145

4246
lights.update(from: old.lights, style: style, initialLights: initial?.lights)
4347

@@ -59,6 +63,8 @@ extension MapContentUniqueProperties {
5963
case terrain
6064
case atmosphere = "fog"
6165
case projection
66+
case snow
67+
case rain
6268
case lights = "lights"
6369
}
6470

@@ -68,6 +74,8 @@ extension MapContentUniqueProperties {
6874
self.terrain = try container.decodeIfPresent(Terrain.self, forKey: .terrain)
6975
self.atmosphere = try container.decodeIfPresent(Atmosphere.self, forKey: .atmosphere)
7076
self.projection = try container.decodeIfPresent(StyleProjection.self, forKey: .projection)
77+
self.snow = try container.decodeIfPresent(Snow.self, forKey: .snow)
78+
self.rain = try container.decodeIfPresent(Rain.self, forKey: .rain)
7179
if var lightContainer = try? container.nestedUnkeyedContainer(forKey: .lights) {
7280
while !lightContainer.isAtEnd {
7381
var lightInfoContainer = lightContainer

Sources/MapboxMaps/Documentation.docc/API Catalogs/Style.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
- ``StyleProjectionName``
2626
- ``CancelError``
2727
- ``TransitionOptions-struct``
28+
- ``Rain``
29+
- ``Snow``
2830

2931
### Declarative Map Styling
3032

0 commit comments

Comments
 (0)