221 lines
8.1 KiB
Swift
221 lines
8.1 KiB
Swift
//
|
|
// EQNSeismic.swift
|
|
// Earthquake Network
|
|
//
|
|
// Created by Busi Andrea on 20/09/2020.
|
|
// Copyright © 2020 Earthquake Network. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
|
|
@objc class EQNSeismic: NSObject {
|
|
|
|
@objc enum FilterType: Int {
|
|
case inRadius
|
|
case positionRelevant
|
|
case worldWide
|
|
case userFelt
|
|
}
|
|
|
|
enum Sort: Int, CaseIterable {
|
|
case time
|
|
case position
|
|
case magnitude
|
|
}
|
|
|
|
@objc static let shared = EQNSeismic()
|
|
|
|
@objc var filterOption: FilterType
|
|
var sort: Sort
|
|
var maximumDistance: String
|
|
@objc var minimumMagnitude: String
|
|
|
|
|
|
// MARK: - Init
|
|
|
|
override init() {
|
|
Self.migrate_v5_8()
|
|
|
|
let defaults = UserDefaults.standard
|
|
filterOption = defaults.enumObject(forKey: UserDefaults.SeismicFilterOption, or: .positionRelevant)
|
|
sort = defaults.enumObject(forKey: UserDefaults.SeismicSort, or: .time)
|
|
maximumDistance = defaults.object(forKey: UserDefaults.SeismicDistanzaMassima, or: EQNData.DefaultFilterRadius.value)
|
|
minimumMagnitude = defaults.object(forKey: UserDefaults.SeismicMagnitudoMinima, or: EQNData.DefaultFilterMagnitude.value)
|
|
|
|
super.init()
|
|
}
|
|
|
|
|
|
// MARK: - Public
|
|
|
|
public func saveFilters() {
|
|
let defaults = UserDefaults.standard
|
|
defaults.set(filterOption.rawValue, forKey: UserDefaults.SeismicFilterOption)
|
|
defaults.set(sort.rawValue, forKey: UserDefaults.SeismicSort)
|
|
defaults.set(maximumDistance, forKey: UserDefaults.SeismicDistanzaMassima)
|
|
defaults.set(minimumMagnitude, forKey: UserDefaults.SeismicMagnitudoMinima)
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private class func migrate_v5_8() {
|
|
let defaults = UserDefaults.standard
|
|
let alreadyMigrated = defaults.bool(forKey: UserDefaults.SismicFiltersMigrationV5_8)
|
|
if alreadyMigrated {
|
|
return
|
|
}
|
|
|
|
if let savedMagnitude = defaults.object(forKey: UserDefaults.SeismicMagnitudoMinima) as? String {
|
|
let minMagnitude = switch savedMagnitude {
|
|
case "0.0": "0.0"
|
|
case "0.5", "1.0": "1.0"
|
|
case "1.5", "2.0": "2.0"
|
|
case "2.5", "3.0": "3.0"
|
|
case "3.5", "4.0": "4.0"
|
|
case "4.5", "5.0": "5.0"
|
|
case "5.5", "6.0": "6.0"
|
|
default: "0.0"
|
|
}
|
|
defaults.set(minMagnitude, forKey: UserDefaults.SeismicMagnitudoMinima)
|
|
}
|
|
|
|
if let savedDistance = defaults.object(forKey: UserDefaults.SeismicDistanzaMassima) as? String {
|
|
let maxDistance = switch savedDistance {
|
|
case "50", "100": "100"
|
|
case "200", "300": "250"
|
|
case "400", "500", "600": "500"
|
|
case "800": "750"
|
|
case "1000": "1000"
|
|
default:
|
|
// 2000, 4000, qualsiasi distanza
|
|
"2000"
|
|
}
|
|
defaults.set(maxDistance, forKey: UserDefaults.SeismicDistanzaMassima)
|
|
}
|
|
|
|
defaults.set(true, forKey: UserDefaults.SismicFiltersMigrationV5_8)
|
|
}
|
|
|
|
// MARK: - Class
|
|
|
|
@objc func filterSeismicList(_ list: [EQNSisma]) -> [EQNSisma] {
|
|
// filtri
|
|
let filter_radius = Double(maximumDistance)
|
|
let filter_min_magnitude = Double(minimumMagnitude)
|
|
|
|
// filter seismic list
|
|
var filtered = [EQNSisma]()
|
|
for (i, seismic) in list.enumerated() {
|
|
var keep = true
|
|
|
|
let latitude = seismic.coordinate.coordinate.latitude
|
|
let longitude = seismic.coordinate.coordinate.longitude
|
|
let provider = seismic.provider.uppercased()
|
|
|
|
//Ricerca di sismi duplicati in lista
|
|
for j in -3...3 {
|
|
if (j != 0) && (i + j > 0) && (i+j < list.count) {
|
|
let seismic_j = list[i+j]
|
|
let latitude_j = seismic_j.coordinate.coordinate.latitude
|
|
let longitude_j = seismic_j.coordinate.coordinate.longitude
|
|
let provider_j = seismic_j.provider.uppercased()
|
|
|
|
let delta_lat = abs(latitude - latitude_j)
|
|
let delta_lon = abs(longitude - longitude_j)
|
|
let delta_time = abs(EQNUtility.getDeltaMinute(seismic.date ?? Date()) - EQNUtility.getDeltaMinute(seismic_j.date ?? Date()))
|
|
let ratio = seismic.magnitude.doubleValue/seismic_j.magnitude.doubleValue
|
|
|
|
if ratio > 0.8 && ratio < 1.2 && delta_lat < 0.5 && delta_lon < 0.5 && delta_time <= 2 {
|
|
if provider == "EMSC" {
|
|
keep = false
|
|
}
|
|
if provider == "USGS" && !(provider_j == "EMSC") {
|
|
keep = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if keep {
|
|
let distance = seismic.userDistance
|
|
let magnitude = seismic.magnitude.doubleValue
|
|
|
|
if filterOption == .inRadius {
|
|
//filtro basato su magnitudo e raggio
|
|
if let filter_radius, let filter_min_magnitude, distance > filter_radius || magnitude < filter_min_magnitude {
|
|
keep = false
|
|
}
|
|
} else if filterOption == .positionRelevant {
|
|
//filtro sismi significativi
|
|
|
|
if magnitude < 7.0 && distance > 2000 {
|
|
keep = false
|
|
} else if magnitude < 6.5 && distance > 1600 {
|
|
keep = false
|
|
} else if magnitude < 6.0 && distance > 1300 {
|
|
keep = false
|
|
} else if magnitude < 5.5 && distance > 1000 {
|
|
keep = false
|
|
} else if magnitude < 5.0 && distance > 700 {
|
|
keep = false
|
|
} else if magnitude < 4.5 && distance > 500 {
|
|
keep = false
|
|
} else if magnitude < 4.0 && distance > 350 {
|
|
keep = false
|
|
} else if magnitude < 3.5 && distance > 200 {
|
|
keep = false
|
|
} else if magnitude < 3.0 && distance > 125 {
|
|
keep = false
|
|
} else if magnitude < 2.5 && distance > 70 {
|
|
keep = false
|
|
} else if magnitude < 2.0 && distance > 35 {
|
|
keep = false
|
|
} else if magnitude < 1.5 && distance > 20 {
|
|
keep = false
|
|
}
|
|
} else if filterOption == .worldWide {
|
|
//filtro che mostra tutti i sismi a livello mondiale di magnitudo>=2
|
|
if magnitude < 2 {
|
|
keep = false
|
|
}
|
|
} else if filterOption == .userFelt {
|
|
//filtro che mostra i sismi segnalati da più di 1 utente
|
|
if seismic.userNumber.intValue < 2 {
|
|
keep = false
|
|
}
|
|
}
|
|
}
|
|
|
|
if keep {
|
|
filtered.append(seismic)
|
|
}
|
|
}
|
|
|
|
switch sort {
|
|
case .time:
|
|
filtered.sort(by: { seismic1, seismic2 in
|
|
guard let date1 = seismic1.date else {
|
|
return false
|
|
}
|
|
|
|
guard let date2 = seismic2.date else {
|
|
return true
|
|
}
|
|
|
|
return date1 > date2
|
|
})
|
|
case .position:
|
|
filtered.sort { seismic1, seismic2 in
|
|
seismic1.userDistance < seismic2.userDistance
|
|
}
|
|
case .magnitude:
|
|
filtered.sort { seismic1, seismic2 in
|
|
seismic1.magnitude.doubleValue > seismic2.magnitude.doubleValue
|
|
}
|
|
}
|
|
|
|
return filtered
|
|
}
|
|
}
|