feat: Add intensity map
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
656E02162C1C4DF2008D0E92 /* EQNBaseContainerTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 656E02152C1C4DF2008D0E92 /* EQNBaseContainerTableViewCell.swift */; };
|
||||
656EB9362A15FD16009DADF3 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 656EB9382A15FD16009DADF3 /* Localizable.stringsdict */; };
|
||||
656EB9412A16288A009DADF3 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 656EB9382A15FD16009DADF3 /* Localizable.stringsdict */; };
|
||||
657415E02D70B6F800F54890 /* EQNMapAnnotationShakemap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657415DE2D70B6F700F54890 /* EQNMapAnnotationShakemap.swift */; };
|
||||
657747FD2D4D12A200213830 /* SeismicNetworkData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657747FC2D4D12A200213830 /* SeismicNetworkData.swift */; };
|
||||
657747FF2D4D2BA200213830 /* SeismicNetworkScrollIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 657747FE2D4D2BA100213830 /* SeismicNetworkScrollIndicatorView.swift */; };
|
||||
6586971125F44C26009C0182 /* EQNBlurredCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6586971025F44C26009C0182 /* EQNBlurredCloseButton.swift */; };
|
||||
@@ -75,8 +76,10 @@
|
||||
65E6AC702C2DB3B60073F8FE /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 65E6AC6F2C2DB3B60073F8FE /* FirebaseMessaging */; };
|
||||
65EA58802A60269C0038EE9D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8C10B0BD2281FE7F00125C9F /* Localizable.strings */; };
|
||||
65EA58822A60360D0038EE9D /* EQNRealtimePushNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65EA58812A60360D0038EE9D /* EQNRealtimePushNotification.swift */; };
|
||||
65F9A6082D706592008A12B5 /* SeismicNetworksIntensityMapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F9A6072D706592008A12B5 /* SeismicNetworksIntensityMapViewController.swift */; };
|
||||
65F9A60A2D706ADC008A12B5 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F9A6092D706ADC008A12B5 /* APIService.swift */; };
|
||||
65F9A60C2D70781A008A12B5 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F9A60B2D70781A008A12B5 /* Log.swift */; };
|
||||
65F9A60E2D707BFE008A12B5 /* EQNShakemap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F9A60D2D707BFE008A12B5 /* EQNShakemap.swift */; };
|
||||
65F9B49C2A8CA22800F13260 /* BackgroundTaskManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F9B49B2A8CA22800F13260 /* BackgroundTaskManager.swift */; };
|
||||
65F9B49E2A8CA2AC00F13260 /* EQNBackgroundPosition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F9B49D2A8CA2AC00F13260 /* EQNBackgroundPosition.swift */; };
|
||||
65F9B4A02A8CC58200F13260 /* UpdateUserLocationTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F9B49F2A8CC58200F13260 /* UpdateUserLocationTask.swift */; };
|
||||
@@ -342,6 +345,7 @@
|
||||
656EB93E2A15FD1E009DADF3 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = it; path = it.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
656EB93F2A15FD1F009DADF3 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = es; path = es.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
656EB9402A15FD1F009DADF3 /* tr-TR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "tr-TR"; path = "tr-TR.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||
657415DE2D70B6F700F54890 /* EQNMapAnnotationShakemap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNMapAnnotationShakemap.swift; sourceTree = "<group>"; };
|
||||
657747FC2D4D12A200213830 /* SeismicNetworkData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworkData.swift; sourceTree = "<group>"; };
|
||||
657747FE2D4D2BA100213830 /* SeismicNetworkScrollIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworkScrollIndicatorView.swift; sourceTree = "<group>"; };
|
||||
6586971025F44C26009C0182 /* EQNBlurredCloseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNBlurredCloseButton.swift; sourceTree = "<group>"; };
|
||||
@@ -379,8 +383,10 @@
|
||||
65DBFB7225E2BBF20041CBA6 /* GADTTemplateView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GADTTemplateView.m; sourceTree = "<group>"; };
|
||||
65DBFB7325E2BBF20041CBA6 /* GADTMediumTemplateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GADTMediumTemplateView.h; sourceTree = "<group>"; };
|
||||
65EA58812A60360D0038EE9D /* EQNRealtimePushNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNRealtimePushNotification.swift; sourceTree = "<group>"; };
|
||||
65F9A6072D706592008A12B5 /* SeismicNetworksIntensityMapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworksIntensityMapViewController.swift; sourceTree = "<group>"; };
|
||||
65F9A6092D706ADC008A12B5 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = "<group>"; };
|
||||
65F9A60B2D70781A008A12B5 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
|
||||
65F9A60D2D707BFE008A12B5 /* EQNShakemap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNShakemap.swift; sourceTree = "<group>"; };
|
||||
65F9B49B2A8CA22800F13260 /* BackgroundTaskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskManager.swift; sourceTree = "<group>"; };
|
||||
65F9B49D2A8CA2AC00F13260 /* EQNBackgroundPosition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNBackgroundPosition.swift; sourceTree = "<group>"; };
|
||||
65F9B49F2A8CC58200F13260 /* UpdateUserLocationTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateUserLocationTask.swift; sourceTree = "<group>"; };
|
||||
@@ -673,6 +679,7 @@
|
||||
children = (
|
||||
653C67FB25F3D63500FE52AC /* EQNMapAnnotationUserReport.swift */,
|
||||
651901B825F5358700CAFF20 /* EQNMapAnnotationSeismic.swift */,
|
||||
657415DE2D70B6F700F54890 /* EQNMapAnnotationShakemap.swift */,
|
||||
654D18C825F93CD700BB6DB0 /* EQNMapAnnotationPastquake.swift */,
|
||||
);
|
||||
path = "Map annotation";
|
||||
@@ -928,6 +935,7 @@
|
||||
DC2814372519C56100C1AFF7 /* SeismicNetworksViewController.swift */,
|
||||
DCC76BD7251F56050005C4DC /* SeismicCardSettingsViewController.swift */,
|
||||
65DBFB4A25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift */,
|
||||
65F9A6072D706592008A12B5 /* SeismicNetworksIntensityMapViewController.swift */,
|
||||
);
|
||||
path = "Seismic Networks";
|
||||
sourceTree = "<group>";
|
||||
@@ -1125,6 +1133,7 @@
|
||||
65EA58812A60360D0038EE9D /* EQNRealtimePushNotification.swift */,
|
||||
6552C1452926DBA1008E723C /* AppPreferences.swift */,
|
||||
6590EFF72C3004EA00F41420 /* EQNOfficialPushNotification.swift */,
|
||||
65F9A60D2D707BFE008A12B5 /* EQNShakemap.swift */,
|
||||
);
|
||||
path = Models;
|
||||
sourceTree = "<group>";
|
||||
@@ -1597,6 +1606,7 @@
|
||||
DC886A5D24E92D5500F7A5D3 /* EQNBaseViewController.m in Sources */,
|
||||
8C593E8A217BA2470008B260 /* EQNSegnalazione.m in Sources */,
|
||||
8CBD3DCA2149B9AD0070C963 /* AllerteViewController.m in Sources */,
|
||||
65F9A60E2D707BFE008A12B5 /* EQNShakemap.swift in Sources */,
|
||||
DC646F32252B698B000AA5FD /* AlertsSeismicNotificationCompactTableViewCell.swift in Sources */,
|
||||
DCF10DCD24D2C935009F34C3 /* EQNPurchaseAvailability.swift in Sources */,
|
||||
6552C1462926DBA1008E723C /* AppPreferences.swift in Sources */,
|
||||
@@ -1644,6 +1654,7 @@
|
||||
8C5EA23D2177B51C002DC156 /* SegnalazioniViewController.m in Sources */,
|
||||
656E02162C1C4DF2008D0E92 /* EQNBaseContainerTableViewCell.swift in Sources */,
|
||||
656D138F2C2225560094F597 /* SubscriptionDetailsViewController.swift in Sources */,
|
||||
65F9A6082D706592008A12B5 /* SeismicNetworksIntensityMapViewController.swift in Sources */,
|
||||
653C67E225F3CC2E00FE52AC /* EQNCustomAnnotationView.swift in Sources */,
|
||||
8CF4F4D8216D3A110057110B /* EQNAreaCheck.m in Sources */,
|
||||
8C4E34452152B707008B0D2A /* EQNAccelerometroManager.m in Sources */,
|
||||
@@ -1666,6 +1677,7 @@
|
||||
8C8EBBA721540039002784BA /* EQNUser.m in Sources */,
|
||||
8CADAA9421B2627D0044E256 /* EQNLogViewController.m in Sources */,
|
||||
DC3BA11124D1A9C90062EE7F /* SubscriptionsViewController.swift in Sources */,
|
||||
657415E02D70B6F800F54890 /* EQNMapAnnotationShakemap.swift in Sources */,
|
||||
DC646F27252B694A000AA5FD /* AlertsSeismicNotificationExpandedTableViewCell.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@@ -62,7 +62,8 @@ extension UserDefaults {
|
||||
static let AppMigrationV5_4 = "EQNUserDefaultMigrationV5_4"
|
||||
static let AppMigrationV5_8 = "EQNUserDefaultMigrationV5_8"
|
||||
static let AppMigrationV5_8_2 = "EQNUserDefaultMigrationV5_8_2"
|
||||
|
||||
static let AppMigrationV5_9 = "EQNUserDefaultMigrationV5_9"
|
||||
|
||||
static let SettingsSeismicNetworkNotificationMigrationV5_8 = "EQNUserDefaultSettingsSeismicNetworkNotificationMigrationV5_8"
|
||||
static let SettingsUserReportNotificationMigrationV5_8 = "EQNUserDefaultSettingsUserReportNotificationMigrationV5_8"
|
||||
static let SismicFiltersMigrationV5_8 = "EQNUserDefaultSismicFiltersMigrationV5_8"
|
||||
|
||||
+23
-5
@@ -15,6 +15,7 @@ protocol SeismicNetworkTableViewCellDelegate: AnyObject {
|
||||
func seismicNetworkCellDidTapShare(_ cell: SeismicNetworkTableViewCell)
|
||||
func seismicNetworkCellDidTapMap(_ cell: SeismicNetworkTableViewCell)
|
||||
func seismicNetworkCellDidTapMapDetail(_ cell: SeismicNetworkTableViewCell)
|
||||
func seismicNetworkCellDidTapIntensityMapDetail(_ cell: SeismicNetworkTableViewCell)
|
||||
func seismicNetworkCellDidTapCalendar(_ cell: SeismicNetworkTableViewCell)
|
||||
func seismicNetworkCellDidTapSettings(_ cell: SeismicNetworkTableViewCell)
|
||||
func seismicNetworkCellDidTapClose(_ cell: SeismicNetworkTableViewCell)
|
||||
@@ -33,6 +34,7 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
case population
|
||||
case realtimeSmartphones
|
||||
case reportUsers
|
||||
case intensityMap
|
||||
case buttons
|
||||
}
|
||||
|
||||
@@ -49,6 +51,7 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
private static let DefaultButtonHeight: CGFloat = 30.0
|
||||
private static let DefaultVerticalSpacing: CGFloat = 6.0
|
||||
|
||||
/// Seismic to show
|
||||
@@ -299,7 +302,7 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
stackViewInformations.trailingAnchor.constraint(equalTo: informationsTrailingAnchor, constant: -14).isActive = true
|
||||
|
||||
previousView = stackViewInformations
|
||||
if informationTypes.contains(.realtimeSmartphones) || informationTypes.contains(.reportUsers) {
|
||||
if informationTypes.contains(.realtimeSmartphones) || informationTypes.contains(.reportUsers) || informationTypes.contains(.intensityMap) {
|
||||
let separator2 = addSeparator(constraintTo: stackViewInformations.bottomAnchor)
|
||||
|
||||
let stackViewReports = UIStackView()
|
||||
@@ -315,11 +318,18 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
if informationTypes.contains(.reportUsers) {
|
||||
stackViewReports.addArrangedSubview(alertsLabel)
|
||||
}
|
||||
if informationTypes.contains(.intensityMap) {
|
||||
let buttonMap = EQNRoundedButton.make(title: "🎯 \(NSLocalizedString("shakemap", comment: ""))", target: self, action: #selector(intensityMapTapped(_:)))
|
||||
stackViewReports.addArrangedSubview(buttonMap)
|
||||
buttonMap.heightAnchor.constraint(equalToConstant: Self.DefaultButtonHeight).isActive = true
|
||||
buttonMap.leadingAnchor.constraint(equalTo: stackViewReports.leadingAnchor).isActive = true
|
||||
buttonMap.trailingAnchor.constraint(equalTo: stackViewReports.trailingAnchor).isActive = true
|
||||
}
|
||||
|
||||
containerView.addSubview(stackViewReports)
|
||||
stackViewReports.topAnchor.constraint(equalTo: separator2.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
|
||||
stackViewReports.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor, constant: 20.0).isActive = true
|
||||
stackViewReports.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor, constant: -20.0).isActive = true
|
||||
stackViewReports.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
||||
stackViewReports.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
||||
|
||||
let separator3 = addSeparator(constraintTo: stackViewReports.bottomAnchor)
|
||||
previousView = separator3
|
||||
@@ -338,7 +348,7 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
stackViewButtons.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackViewButtons.axis = .horizontal
|
||||
stackViewButtons.distribution = .fillEqually
|
||||
stackViewButtons.spacing = 4
|
||||
stackViewButtons.spacing = 8
|
||||
|
||||
let buttonMap = EQNRoundedButton.make(title: "🗺", target: self, action: #selector(mapTapped(_:)))
|
||||
stackViewButtons.addArrangedSubview(buttonMap)
|
||||
@@ -348,7 +358,7 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
stackViewButtons.addArrangedSubview(buttonSettings)
|
||||
|
||||
containerView.addSubview(stackViewButtons)
|
||||
stackViewButtons.heightAnchor.constraint(equalToConstant: 30.0).isActive = true
|
||||
stackViewButtons.heightAnchor.constraint(equalToConstant: Self.DefaultButtonHeight).isActive = true
|
||||
stackViewButtons.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
|
||||
stackViewButtons.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
||||
stackViewButtons.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
||||
@@ -370,6 +380,7 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
let buttonClose = EQNRoundedButton.make(title: NSLocalizedString("official_close", comment: "").uppercased(), target: self, action: #selector(closeTapped(_:)))
|
||||
|
||||
containerView.addSubview(buttonClose)
|
||||
buttonClose.heightAnchor.constraint(equalToConstant: Self.DefaultButtonHeight).isActive = true
|
||||
buttonClose.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Self.DefaultVerticalSpacing).isActive = true
|
||||
buttonClose.leadingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.leadingAnchor).isActive = true
|
||||
buttonClose.trailingAnchor.constraint(equalTo: containerView.layoutMarginsGuide.trailingAnchor).isActive = true
|
||||
@@ -470,6 +481,9 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
if seismic.userNumber.intValue > 0 && !informations.contains(.reportUsers) {
|
||||
self.informationTypes += [.reportUsers]
|
||||
}
|
||||
if seismic.isoCode == "0" && informations.contains(.intensityMap) {
|
||||
self.informationTypes.removeAll { $0 == .intensityMap }
|
||||
}
|
||||
|
||||
recreateUI()
|
||||
updateUI()
|
||||
@@ -503,6 +517,10 @@ class SeismicNetworkTableViewCell: UITableViewCell {
|
||||
delegate?.seismicNetworkCellDidTapMapDetail(self)
|
||||
}
|
||||
|
||||
@objc func intensityMapTapped(_ sender: Any) {
|
||||
delegate?.seismicNetworkCellDidTapIntensityMapDetail(self)
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
@discardableResult
|
||||
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
//
|
||||
// SeismicNetworksIntensityMapViewController.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 27/02/25.
|
||||
// Copyright © 2025 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
|
||||
class SeismicNetworksIntensityMapViewController: EQNBaseMapViewController {
|
||||
|
||||
private let seismic: EQNSisma
|
||||
private var shakemaps: [EQNShakemap] = []
|
||||
private var pinStyle: EQNSeismicAnnotationView.Style = .circle
|
||||
|
||||
override var isFilterViewVisible: Bool { false }
|
||||
override var isCloseButtonVisible: Bool { false }
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
init(
|
||||
seismic: EQNSisma
|
||||
) {
|
||||
self.seismic = seismic
|
||||
super.init()
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("Plase use init(seismic:) instead")
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
override func extraUI() {
|
||||
super.extraUI()
|
||||
|
||||
let descriptionView = UIView()
|
||||
descriptionView.translatesAutoresizingMaskIntoConstraints = false
|
||||
descriptionView.backgroundColor = AppTheme.Colors.pureBlue
|
||||
view.addSubview(descriptionView)
|
||||
descriptionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||
descriptionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
descriptionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
|
||||
let descriptionLabel = UILabel()
|
||||
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
descriptionLabel.numberOfLines = 0
|
||||
descriptionLabel.textColor = .white
|
||||
descriptionLabel.font = .preferredFont(forTextStyle: .subheadline)
|
||||
descriptionLabel.textAlignment = .center
|
||||
descriptionLabel.text = NSLocalizedString("shakemap_description", comment: "")
|
||||
|
||||
descriptionView.addSubview(descriptionLabel)
|
||||
descriptionLabel.leadingAnchor.constraint(equalTo: descriptionView.leadingAnchor, constant: 2.0).isActive = true
|
||||
descriptionLabel.trailingAnchor.constraint(equalTo: descriptionView.trailingAnchor, constant: -2.0).isActive = true
|
||||
descriptionLabel.topAnchor.constraint(equalTo: descriptionView.topAnchor, constant: 2.0).isActive = true
|
||||
descriptionLabel.bottomAnchor.constraint(equalTo: descriptionView.bottomAnchor, constant: -2.0).isActive = true
|
||||
}
|
||||
|
||||
override func configureUI() {
|
||||
super.configureUI()
|
||||
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem(systemItem: .done, primaryAction: .init(handler: { [weak self] _ in
|
||||
self?.dismiss(animated: true)
|
||||
}))
|
||||
navigationItem.rightBarButtonItems = [
|
||||
UIBarButtonItem(image: UIImage(named: "navbar-icon-screenshot"), primaryAction: .init(handler: { [weak self] _ in
|
||||
self?.shareScreenshot()
|
||||
})),
|
||||
UIBarButtonItem(image: UIImage(named: "navbar-icon-pin-arrow"), primaryAction: .init(handler: { [weak self] _ in
|
||||
self?.nextPinStyle()
|
||||
})),
|
||||
]
|
||||
}
|
||||
|
||||
override func registerMapAnnotationViews() {
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.Style.full.identifier)
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.Style.light.identifier)
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.Style.circle.identifier)
|
||||
}
|
||||
|
||||
override func loadDataSource() {
|
||||
Task {
|
||||
let result = try await APIService.shared.fetchShakemap(isoCode: seismic.isoCode)
|
||||
elaborateShakemaps(result)
|
||||
}
|
||||
}
|
||||
|
||||
override func elaborateMapCenter() {
|
||||
setMapCenter(for: seismic.coordinate, span: MKCoordinateSpan(latitudeDelta: 2, longitudeDelta: 2))
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func elaborateShakemaps(_ shakemaps: [EQNShakemap]) {
|
||||
self.shakemaps = shakemaps
|
||||
|
||||
var shakemapPolyline = [MKPolyline]()
|
||||
var shakemapAnnotations: [MKAnnotation] = []
|
||||
for shakemap in shakemaps {
|
||||
// create coordinates for current shakemap
|
||||
let coordinates = zip(shakemap.lat, shakemap.lon).map { lat, lon in
|
||||
CLLocationCoordinate2D(latitude: Double(lat) / 10_000.0, longitude: Double(lon) / 10_000.0)
|
||||
}
|
||||
|
||||
let intensityColors = getColors(for: shakemap.intensity)
|
||||
|
||||
// create line to show on map
|
||||
let polyline = ShakemapPolyline(coordinates: coordinates, count: coordinates.count)
|
||||
polyline.intensity = shakemap.intensity
|
||||
polyline.intensityColor = intensityColors.lineColor
|
||||
shakemapPolyline.append(polyline)
|
||||
|
||||
// create annotation to show on top of the line
|
||||
let middlePoint = coordinates[coordinates.count / 2]
|
||||
let annotation = EQNMapAnnotationShakemap(coordinate: middlePoint, shakemap: shakemap)
|
||||
annotation.intensityColor = intensityColors.lineColor
|
||||
annotation.intensityTextColor = intensityColors.textColor
|
||||
shakemapAnnotations.append(annotation)
|
||||
}
|
||||
|
||||
let seismicAnnotation = EQNMapAnnotationSeismic(seismic: seismic)
|
||||
shakemapAnnotations.append(seismicAnnotation)
|
||||
|
||||
// draw lines
|
||||
mapView.addOverlays(shakemapPolyline)
|
||||
updateMap(with: shakemapAnnotations)
|
||||
}
|
||||
|
||||
private func nextPinStyle() {
|
||||
pinStyle = pinStyle.next()
|
||||
reloadMap()
|
||||
}
|
||||
|
||||
private func shareScreenshot() {
|
||||
let screenshot = createSnapshot()
|
||||
|
||||
let controller = UIActivityViewController(activityItems: [screenshot], applicationActivities: [])
|
||||
present(controller, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - MKMapViewDelegate
|
||||
|
||||
override func setupAnnotationView(for annotation: MKAnnotation, on mapView: MKMapView) -> MKAnnotationView? {
|
||||
switch annotation {
|
||||
case let shakemapAnnotation as EQNMapAnnotationShakemap:
|
||||
return shakemapAnnotation.toAnnotationView(mapView: mapView, style: .light)
|
||||
case let seismicAnnotation as EQNMapAnnotationSeismic:
|
||||
return seismicAnnotation.toAnnotationView(mapView: mapView, style: pinStyle)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
||||
if let polyline = overlay as? ShakemapPolyline {
|
||||
let renderer = MKPolylineRenderer(polyline: polyline)
|
||||
renderer.strokeColor = polyline.intensityColor
|
||||
renderer.lineWidth = 6.0
|
||||
return renderer
|
||||
}
|
||||
return MKOverlayRenderer()
|
||||
}
|
||||
|
||||
private func getColors(for intensity: Float) -> (textColor: UIColor, lineColor: UIColor) {
|
||||
let shakemapColors: [String] = [
|
||||
"#3E26A8","#3E27AC","#3F28AF","#3F29B2","#402AB4","#402BB7","#412CBA","#412DBD","#422EBF","#422FC2",
|
||||
"#4330C5","#4331C8","#4332CA","#4433CD","#4434D0","#4535D2","#4537D5","#4538D7","#4639D9","#463ADC",
|
||||
"#463BDE","#463DE0","#473EE1","#473FE3","#4741E5","#4742E6","#4744E8","#4745E9","#4746EB","#4848EC",
|
||||
"#4849ED","#484BEE","#484CF0","#484EF1","#484FF2","#4850F3","#4852F4","#4853F5","#4854F6","#4756F7",
|
||||
"#4757F7","#4759F8","#475AF9","#475BFA","#475DFA","#465EFB","#4660FB","#4661FC","#4562FC","#4564FD",
|
||||
"#4465FD","#4367FD","#4368FE","#426AFE","#416BFE","#406DFE","#3F6EFF","#3E70FF","#3C71FF","#3B73FF",
|
||||
"#3974FF","#3876FE","#3677FE","#3579FD","#337AFD","#327CFC","#317DFC","#307FFB","#2F80FA","#2F82FA",
|
||||
"#2E83F9","#2E84F8","#2E86F8","#2E87F7","#2D88F6","#2D8AF5","#2D8BF4","#2D8CF3","#2D8EF2","#2C8FF1",
|
||||
"#2C90F0","#2B91EF","#2A93EE","#2994ED","#2895EC","#2797EB","#2798EA","#2699E9","#269AE8","#259BE8",
|
||||
"#259CE7","#249EE6","#249FE5","#23A0E5","#23A1E4","#22A2E4","#21A3E3","#20A5E3","#1FA6E2","#1EA7E1",
|
||||
"#1DA8E1","#1DA9E0","#1CAADF","#1BABDE","#1AACDD","#19ADDC","#17AEDA","#16AFD9","#14B0D8","#12B1D6",
|
||||
"#10B2D5","#0EB3D4","#0BB3D2","#08B4D1","#06B5CF","#04B6CE","#02B7CC","#01B7CA","#00B8C9","#00B9C7",
|
||||
"#00BAC6","#01BAC4","#02BBC2","#04BBC1","#06BCBF","#09BDBD","#0DBDBC","#10BEBA","#14BEB8","#17BFB6",
|
||||
"#1AC0B5","#1DC0B3","#20C1B1","#23C1AF","#25C2AE","#27C2AC","#29C3AA","#2BC3A8","#2CC4A6","#2EC4A5",
|
||||
"#2FC5A3","#31C5A1","#32C69F","#33C79D","#35C79B","#36C899","#38C896","#39C994","#3BC992","#3DCA90",
|
||||
"#40CA8D","#42CA8B","#45CB89","#48CB86","#4BCB84","#4ECC81","#51CC7F","#54CC7C","#57CC7A","#5ACC77",
|
||||
"#5ECD74","#61CD72","#64CD6F","#67CD6C","#6BCD69","#6ECD66","#72CD64","#76CC61","#79CC5E","#7DCC5B",
|
||||
"#81CC59","#84CC56","#88CB53","#8BCB51","#8FCB4E","#93CA4B","#96CA48","#9AC946","#9DC943","#A1C840",
|
||||
"#A4C83E","#A7C73B","#ABC739","#AEC637","#B2C635","#B5C533","#B8C431","#BBC42F","#BEC32D","#C2C32C",
|
||||
"#C5C22A","#C8C129","#CBC128","#CEC027","#D0BF27","#D3BF27","#D6BE27","#D9BE28","#DBBD28","#DEBC29",
|
||||
"#E1BC2A","#E3BC2B","#E6BB2D","#E8BB2E","#EABA30","#ECBA32","#EFBA35","#F1BA37","#F3BA39","#F5BA3B",
|
||||
"#F7BA3D","#F9BA3E","#FBBB3E","#FCBC3E","#FEBD3D","#FEBE3C","#FEC03B","#FEC13A","#FEC239","#FEC438",
|
||||
"#FEC537","#FEC735","#FEC834","#FECA33","#FDCB32","#FDCD31","#FDCE31","#FCD030","#FBD22F","#FBD32E",
|
||||
"#FAD52E","#F9D62D","#F9D82C","#F8D92B","#F7DB2A","#F7DD2A","#F6DE29","#F6E028","#F5E128","#F5E327",
|
||||
"#F5E526","#F5E626","#F5E825","#F5E924","#F5EB23","#F5EC22","#F5EE21","#F6EF20","#F6F11F","#F6F21E",
|
||||
"#F7F41C","#F7F51B","#F8F71A","#F8F818","#F9F916","#F9FB15"
|
||||
]
|
||||
|
||||
let minIntensity = shakemaps.map { $0.intensity }.min() ?? 0
|
||||
let maxIntensity = shakemaps.map { $0.intensity }.max() ?? 255
|
||||
let indexColor = Int(round((intensity-minIntensity)/(maxIntensity-minIntensity)*255))
|
||||
|
||||
let lineColor = UIColor(hexString: shakemapColors[indexColor]) ?? .white
|
||||
let textColor: UIColor = indexColor < 65 ? .white : .black
|
||||
|
||||
return (textColor: textColor, lineColor: lineColor)
|
||||
}
|
||||
}
|
||||
|
||||
extension EQNMapAnnotationShakemap {
|
||||
func toAnnotationView(
|
||||
mapView: MKMapView,
|
||||
style: EQNSeismicAnnotationView.Style,
|
||||
isUserSelection: Bool = false
|
||||
) -> MKAnnotationView? {
|
||||
switch style {
|
||||
case .full, .light:
|
||||
let identifier = style.identifier
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: self) as! EQNSeismicAnnotationView
|
||||
annotationView.magnitude = String(format: "M%.1f", shakemap.intensity)
|
||||
annotationView.magnitudeTextColor = intensityTextColor ?? .black
|
||||
annotationView.magnitudeBackgroundColor = intensityColor
|
||||
return annotationView
|
||||
case .circle:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate class ShakemapPolyline: MKPolyline {
|
||||
var intensity: Float = 0
|
||||
var intensityColor: UIColor = .white
|
||||
}
|
||||
+31
-33
@@ -15,21 +15,8 @@ protocol SeismicNetworksMapDetailViewControllerDelegate: AnyObject {
|
||||
}
|
||||
|
||||
class SeismicNetworksMapDetailViewController: EQNBaseMapViewController {
|
||||
|
||||
private enum PinStyle: CaseIterable {
|
||||
case full
|
||||
case light
|
||||
case circle
|
||||
|
||||
func next() -> Self {
|
||||
let all = Self.allCases
|
||||
let idx = all.firstIndex(of: self)!
|
||||
let next = all.index(after: idx)
|
||||
return all[next == all.endIndex ? all.startIndex : next]
|
||||
}
|
||||
}
|
||||
|
||||
private var pinStyle: PinStyle = .full
|
||||
private var pinStyle: EQNSeismicAnnotationView.Style = .full
|
||||
private let eqnSeismic = EQNSeismic.shared
|
||||
|
||||
// MARK: - State
|
||||
@@ -116,9 +103,9 @@ class SeismicNetworksMapDetailViewController: EQNBaseMapViewController {
|
||||
}
|
||||
|
||||
override func registerMapAnnotationViews() {
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.IdentifierFull)
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.IdentifierLight)
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.IdentifierCircle)
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.Style.full.identifier)
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.Style.light.identifier)
|
||||
mapView.register(EQNSeismicAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNSeismicAnnotationView.Style.circle.identifier)
|
||||
}
|
||||
|
||||
override func loadDataSource() {
|
||||
@@ -241,22 +228,7 @@ class SeismicNetworksMapDetailViewController: EQNBaseMapViewController {
|
||||
}
|
||||
|
||||
let isUserSelection = annotation.seismic == seismic
|
||||
switch pinStyle {
|
||||
case .full, .light:
|
||||
let identifier = pinStyle == .full ? EQNSeismicAnnotationView.IdentifierFull : EQNSeismicAnnotationView.IdentifierLight
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as! EQNSeismicAnnotationView
|
||||
annotationView.title = annotation.title
|
||||
annotationView.subtitle = annotation.subtitle
|
||||
annotationView.magnitude = String(format: "M%.1f", annotation.seismic.magnitude.doubleValue)
|
||||
annotationView.magnitudeColor = annotation.textColor
|
||||
annotationView.isUserSelection = isUserSelection
|
||||
return annotationView
|
||||
case .circle:
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: EQNSeismicAnnotationView.IdentifierCircle, for: annotation) as! EQNSeismicAnnotationView
|
||||
annotationView.image = annotation.image(height: EQNSeismicAnnotationView.CircleViewHeight,
|
||||
isUserSelection: isUserSelection)
|
||||
return annotationView
|
||||
}
|
||||
return annotation.toAnnotationView(mapView: mapView, style: pinStyle, isUserSelection: isUserSelection)
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
|
||||
@@ -271,6 +243,32 @@ class SeismicNetworksMapDetailViewController: EQNBaseMapViewController {
|
||||
}
|
||||
}
|
||||
|
||||
extension EQNMapAnnotationSeismic {
|
||||
func toAnnotationView(
|
||||
mapView: MKMapView,
|
||||
style: EQNSeismicAnnotationView.Style,
|
||||
isUserSelection: Bool = false
|
||||
) -> MKAnnotationView {
|
||||
switch style {
|
||||
case .full, .light:
|
||||
let identifier = style.identifier
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: self) as! EQNSeismicAnnotationView
|
||||
annotationView.title = self.title
|
||||
annotationView.subtitle = self.subtitle
|
||||
annotationView.magnitude = String(format: "M%.1f", self.seismic.magnitude.doubleValue)
|
||||
annotationView.magnitudeTextColor = self.textColor
|
||||
annotationView.magnitudeBackgroundColor = .white
|
||||
annotationView.isUserSelection = isUserSelection
|
||||
return annotationView
|
||||
case .circle:
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: style.identifier, for: self) as! EQNSeismicAnnotationView
|
||||
annotationView.image = image(height: EQNSeismicAnnotationView.CircleViewHeight,
|
||||
isUserSelection: isUserSelection)
|
||||
return annotationView
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SeismicNetworksMapDetailViewController: SeismicFiltersViewControllerDelegate {
|
||||
func seismicFiltersControllerDidUpdateFilters(_ controller: SeismicFiltersViewController) {
|
||||
delegate?.seismicNetworksMapDetailControllerWillUpdateData(self, needsDataUpdate: controller.needsDataUpdate)
|
||||
|
||||
+12
@@ -238,6 +238,12 @@ class SeismicNetworksViewController: UIViewController, UITableViewDelegate, UITa
|
||||
self.currentMapController = controller
|
||||
}
|
||||
|
||||
private func showIntensityMap(for seismic: EQNSisma) {
|
||||
let controller = SeismicNetworksIntensityMapViewController(seismic: seismic)
|
||||
let navController = UINavigationController(rootViewController: controller)
|
||||
present(navController, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Notifications
|
||||
|
||||
@objc func didReceiveDownloadCompleteNotification(_ sender: Notification) {
|
||||
@@ -782,6 +788,12 @@ extension SeismicNetworksViewController: SeismicNetworkTableViewCellDelegate {
|
||||
showMapDetail(for: seismic)
|
||||
}
|
||||
|
||||
func seismicNetworkCellDidTapIntensityMapDetail(_ cell: SeismicNetworkTableViewCell) {
|
||||
guard let index = tableView.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
|
||||
|
||||
showIntensityMap(for: seismic)
|
||||
}
|
||||
|
||||
func seismicNetworkCellDidTapCalendar(_ cell: SeismicNetworkTableViewCell) {
|
||||
guard let index = tableView.indexPath(for: cell), case let .seismic(seismic) = rows[index.row] else { return }
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ public class EQNUserDefaultsCommand: EQNCommandProtocol {
|
||||
migrationV5_8()
|
||||
migrationFirstAppStat()
|
||||
migrationCriticalAlerts()
|
||||
migrationV5_9()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
@@ -30,7 +31,7 @@ public class EQNUserDefaultsCommand: EQNCommandProtocol {
|
||||
|
||||
// seismic card settings
|
||||
if UserDefaults.standard.array(forKey: EQNUserDefaultKeySesmicInformations) == nil {
|
||||
let informations: [SeismicNetworkTableViewCell.InformationType] = [.buttons, .distance, .coordinate, .population]
|
||||
let informations: [SeismicNetworkTableViewCell.InformationType] = [.buttons, .distance, .coordinate, .population, .intensityMap]
|
||||
UserDefaults.standard.set(informations.map { $0.rawValue }, forKey: EQNUserDefaultKeySesmicInformations)
|
||||
}
|
||||
}
|
||||
@@ -107,4 +108,24 @@ public class EQNUserDefaultsCommand: EQNCommandProtocol {
|
||||
|
||||
userDefaults.set(true, forKey: UserDefaults.AppMigrationV5_8_2)
|
||||
}
|
||||
|
||||
private func migrationV5_9() {
|
||||
let userDefaults = UserDefaults.standard
|
||||
let migrationPerformed = userDefaults.bool(forKey: UserDefaults.AppMigrationV5_9)
|
||||
if migrationPerformed {
|
||||
print("[EQNUserDefaultsCommand] Migration v5.9 already performed")
|
||||
return
|
||||
}
|
||||
|
||||
if let saved = userDefaults.array(forKey: EQNUserDefaultKeySesmicInformations) as? [Int] {
|
||||
var informations = saved.compactMap { SeismicNetworkTableViewCell.InformationType(rawValue: $0) }
|
||||
if !informations.contains(.intensityMap) {
|
||||
informations.append(.intensityMap)
|
||||
print("[EQNUserDefaultsCommand] Add intensityMap to seismic informations")
|
||||
}
|
||||
userDefaults.set(informations.map { $0.rawValue }, forKey: EQNUserDefaultKeySesmicInformations)
|
||||
}
|
||||
|
||||
userDefaults.set(true, forKey: UserDefaults.AppMigrationV5_9)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property (nonatomic, strong) NSNumber *preliminary;
|
||||
@property (nonatomic, strong) NSNumber *smartphoneNumber;
|
||||
@property (nonatomic, strong) NSNumber *userNumber;
|
||||
/// Code to show "intensity map"
|
||||
@property (nonatomic, strong) NSString *isoCode;
|
||||
|
||||
- (instancetype)initWithInfo:(NSDictionary *)info;
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
self.preliminary = info[@"py"];
|
||||
self.smartphoneNumber = info[@"sm"];
|
||||
self.userNumber = info[@"rp"];
|
||||
|
||||
self.isoCode = info[@"iso"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -65,6 +67,7 @@
|
||||
[encoder encodeObject:self.preliminary forKey:@"preliminary"];
|
||||
[encoder encodeObject:self.smartphoneNumber forKey:@"smartphoneNumber"];
|
||||
[encoder encodeObject:self.userNumber forKey:@"userNumber"];
|
||||
[encoder encodeObject:self.isoCode forKey:@"isoCode"];
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder
|
||||
@@ -86,6 +89,7 @@
|
||||
self.preliminary = [decoder decodeObjectForKey:@"preliminary"];
|
||||
self.smartphoneNumber = [decoder decodeObjectForKey:@"smartphoneNumber"];
|
||||
self.userNumber = [decoder decodeObjectForKey:@"userNumber"];
|
||||
self.isoCode = [decoder decodeObjectForKey:@"isoCode"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// EQNMapAnnotationShakemap.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 27/02/25.
|
||||
// Copyright © 2025 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
|
||||
class EQNMapAnnotationShakemap: NSObject, MKAnnotation {
|
||||
let coordinate: CLLocationCoordinate2D
|
||||
let shakemap: EQNShakemap
|
||||
var intensityColor: UIColor?
|
||||
var intensityTextColor: UIColor?
|
||||
|
||||
let title: String? = nil
|
||||
let subtitle: String? = nil
|
||||
|
||||
|
||||
init(
|
||||
coordinate: CLLocationCoordinate2D,
|
||||
shakemap: EQNShakemap
|
||||
) {
|
||||
self.coordinate = coordinate
|
||||
self.shakemap = shakemap
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,26 @@ import MapKit
|
||||
|
||||
class EQNSeismicAnnotationView: MKAnnotationView {
|
||||
|
||||
static let IdentifierFull = "EQNSeismicAnnotationViewFull"
|
||||
static let IdentifierLight = "EQNSeismicAnnotationViewLight"
|
||||
static let IdentifierCircle = "EQNSeismicAnnotationViewCircle"
|
||||
|
||||
enum Style: CaseIterable {
|
||||
case circle
|
||||
case light
|
||||
case full
|
||||
|
||||
var identifier: String {
|
||||
return switch self {
|
||||
case .circle: "EQNSeismicAnnotationViewCircle"
|
||||
case .light: "EQNSeismicAnnotationViewLight"
|
||||
case .full: "EQNSeismicAnnotationViewFull"
|
||||
}
|
||||
}
|
||||
|
||||
func next() -> Self {
|
||||
let all = Self.allCases
|
||||
let idx = all.firstIndex(of: self)!
|
||||
let next = all.index(after: idx)
|
||||
return all[next == all.endIndex ? all.startIndex : next]
|
||||
}
|
||||
}
|
||||
|
||||
private static let LabelHeight: CGFloat = 15.0
|
||||
private static let MagnitudeHeight: CGFloat = 25.0
|
||||
@@ -43,11 +59,16 @@ class EQNSeismicAnnotationView: MKAnnotationView {
|
||||
get { magnitudeLabel.text }
|
||||
}
|
||||
|
||||
var magnitudeColor: UIColor {
|
||||
var magnitudeTextColor: UIColor {
|
||||
set { magnitudeLabel.textColor = newValue }
|
||||
get { magnitudeLabel.textColor }
|
||||
}
|
||||
|
||||
var magnitudeBackgroundColor: UIColor? {
|
||||
set { magnitudeView.backgroundColor = newValue }
|
||||
get { magnitudeView.backgroundColor }
|
||||
}
|
||||
|
||||
var isUserSelection: Bool = false {
|
||||
didSet {
|
||||
magnitudeView.layer.borderColor = isUserSelection ? AppTheme.Colors.red.cgColor : AppTheme.Colors.darkGray.cgColor
|
||||
@@ -107,13 +128,13 @@ class EQNSeismicAnnotationView: MKAnnotationView {
|
||||
|
||||
backgroundColor = .clear
|
||||
|
||||
if reuseIdentifier == Self.IdentifierFull {
|
||||
if reuseIdentifier == Style.full.identifier {
|
||||
frame = CGRect(x: 0, y: 0, width: Self.FullViewWidth, height: Self.FullViewHeight)
|
||||
setupFullUI()
|
||||
} else if reuseIdentifier == Self.IdentifierLight {
|
||||
} else if reuseIdentifier == Style.light.identifier {
|
||||
frame = CGRect(x: 0, y: 0, width: Self.SmallViewWidth, height: Self.SmallViewHeight)
|
||||
setupLightUI()
|
||||
} else if reuseIdentifier == Self.IdentifierCircle {
|
||||
} else if reuseIdentifier == Style.circle.identifier {
|
||||
frame = CGRect(x: 0, y: 0, width: Self.CircleViewHeight, height: Self.CircleViewHeight)
|
||||
setupCircleUI()
|
||||
}
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "\U200FXI - تدمير مراكز حضرية بأكملها ، العديد من الضحايا ، شقوق في الأرض وانهيارات أرضيةlandslides";
|
||||
"mercalli_XII" = "\U200FXII - اضطراب التربة ، إزاحة قشرة الأرض";
|
||||
"mercalli_intensity" = "شدة %@";
|
||||
"shakemap" = "خريطة اهتزازية";
|
||||
"shakemap_description" = "خريطة الكثافة بناءً على التقارير المحسوسة";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "درجة >= 0.0";
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "XI - Καταστροφές ολόκληρων αστικών κέντρων, πολλά θύματα, ρωγμές στο έδαφος και κατολισθήσεις";
|
||||
"mercalli_XII" = "XII - Διάσπαση του εδάφους, μετατόπιση του φλοιού της γης";
|
||||
"mercalli_intensity" = "Ένταση %@";
|
||||
"shakemap" = "Χάρτης έντασης";
|
||||
"shakemap_description" = "Χάρτης έντασης με βάση τις αναφορές χρηστών";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Μέγεθος >= 0.0";
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "XI - Destruction of entire urban centers, many victims, crevices in the ground and landslides";
|
||||
"mercalli_XII" = "XII - Disruption of the soil, displacement of the earth's crust";
|
||||
"mercalli_intensity" = "Intensity %@";
|
||||
"shakemap" = "Shakemap";
|
||||
"shakemap_description" = "Intensity map based on user reports";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitude >= 0.0";
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "XI - Destrucción de centros urbanos enteros, muchas víctimas, grietas en el suelo y deslizamientos de tierra";
|
||||
"mercalli_XII" = "XII - Alteración del suelo, desplazamiento de la corteza terrestre.";
|
||||
"mercalli_intensity" = "Intensidad %@";
|
||||
"shakemap" = "Mapa intensidad";
|
||||
"shakemap_description" = "Mapa de intensidad basado en informes de usuarios";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitud >= 0.0";
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "XI - Destruction de centres urbains entiers, nombreuses victimes, crevasses dans le sol et glissements de terrain";
|
||||
"mercalli_XII" = "XII - Perturbation du sol, déplacement de la croûte terrestre";
|
||||
"mercalli_intensity" = "Intensité %@";
|
||||
"shakemap" = "Carte d'intensité";
|
||||
"shakemap_description" = "Carte d'intensité basée sur les rapports ressentis";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitude >= 0.0";
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "XI - Uništavanje čitavih urbanih središta, mnogo žrtava, pukotine u zemlji i klizišta";
|
||||
"mercalli_XII" = "XII - Poremećaj tla, pomicanje zemljine kore";
|
||||
"mercalli_intensity" = "Intenzitet %@";
|
||||
"shakemap" = "Mapa intenziteta";
|
||||
"shakemap_description" = "Karta intenziteta na temelju izvješća o filu";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Jačina >= 0.0";
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "XI - Penghancuran seluruh pusat kota, banyak korban, celah-celah di tanah dan tanah longsor";
|
||||
"mercalli_XII" = "XII - Gangguan tanah, perpindahan kerak bumi";
|
||||
"mercalli_intensity" = "Intensitas %@";
|
||||
"shakemap" = "Peta intensitas";
|
||||
"shakemap_description" = "Peta intensitas berdasarkan laporan pengguna";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitudo >= 0.0";
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "XI - Distruzione di interi centri urbani, moltissime vittime, crepacci nel suolo e frane ";
|
||||
"mercalli_XII" = "XII - Sconvolgimento del suolo, dislocamento della crosta terrestre";
|
||||
"mercalli_intensity" = "Intensità %@";
|
||||
"shakemap" = "Mappa intensità";
|
||||
"shakemap_description" = "Mappa di intensità basata sulle segnalazioni degli utenti";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitudo >= 0.0";
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"mercalli_XI" = "XI - Tüm şehir merkezlerinin, birçok kurbanın, zemindeki yarıkların ve toprak kaymalarının yok edilmesi";
|
||||
"mercalli_XII" = "XII - Toprağın bozulması, yer kabuğunun yer değiştirmesi";
|
||||
"mercalli_intensity" = "Şiddeti %@";
|
||||
"shakemap" = "Yoğunluk haritası";
|
||||
"shakemap_description" = "Kullanıcı raporlarına dayalı yoğunluk haritası";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Büyüklük >= 0.0";
|
||||
|
||||
Reference in New Issue
Block a user