feat: Align user report map to Android app
@@ -13,7 +13,6 @@
|
||||
652C37BD26092B3C0068EC3B /* FiltersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 652C37BC26092B3C0068EC3B /* FiltersViewModel.swift */; };
|
||||
6531185928425B89006CBC29 /* NotificationService+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6531185828425B89006CBC29 /* NotificationService+Extension.swift */; };
|
||||
65355FFF25F38D3300BB57D2 /* SegnalazioniMapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65355FFE25F38D3300BB57D2 /* SegnalazioniMapViewController.swift */; };
|
||||
6535600425F398CD00BB57D2 /* Costanti+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6535600325F398CD00BB57D2 /* Costanti+Extensions.swift */; };
|
||||
653604E9262348FA00B2B651 /* EQNBaseMapFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653604E8262348FA00B2B651 /* EQNBaseMapFilter.swift */; };
|
||||
653C67E225F3CC2E00FE52AC /* EQNCustomAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653C67E125F3CC2E00FE52AC /* EQNCustomAnnotationView.swift */; };
|
||||
653C67E625F3CC8400FE52AC /* EQNCustomAnnotationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653C67E125F3CC2E00FE52AC /* EQNCustomAnnotationView.swift */; };
|
||||
@@ -138,6 +137,9 @@
|
||||
65CB83432915720400EE1E35 /* EQNUserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65CB83422915720400EE1E35 /* EQNUserData.swift */; };
|
||||
65D409942619BA34008CF356 /* SegnalazioniSendReportCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D409932619BA34008CF356 /* SegnalazioniSendReportCell.swift */; };
|
||||
65D9938A29219DEC00F2B0EB /* UIKit+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65583A04261B83BE00ECA9F9 /* UIKit+Extensions.swift */; };
|
||||
65D9938C2922647800F2B0EB /* AppTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC52B8A424FCCD6900ABEBA6 /* AppTheme.swift */; };
|
||||
65D9938E292264F800F2B0EB /* Foundation+EQNExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D9938D292264F800F2B0EB /* Foundation+EQNExtensions.swift */; };
|
||||
65D9938F2922652100F2B0EB /* Foundation+EQNExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65D9938D292264F800F2B0EB /* Foundation+EQNExtensions.swift */; };
|
||||
65DBFB4B25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DBFB4A25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift */; };
|
||||
65DBFB7425E2BBF20041CBA6 /* GADTMediumTemplateView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 65DBFB6F25E2BBF20041CBA6 /* GADTMediumTemplateView.xib */; };
|
||||
65DBFB7525E2BBF20041CBA6 /* GADTMediumTemplateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 65DBFB7125E2BBF20041CBA6 /* GADTMediumTemplateView.m */; };
|
||||
@@ -296,7 +298,6 @@
|
||||
652C37BC26092B3C0068EC3B /* FiltersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiltersViewModel.swift; sourceTree = "<group>"; };
|
||||
6531185828425B89006CBC29 /* NotificationService+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationService+Extension.swift"; sourceTree = "<group>"; };
|
||||
65355FFE25F38D3300BB57D2 /* SegnalazioniMapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegnalazioniMapViewController.swift; sourceTree = "<group>"; };
|
||||
6535600325F398CD00BB57D2 /* Costanti+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Costanti+Extensions.swift"; sourceTree = "<group>"; };
|
||||
653604E8262348FA00B2B651 /* EQNBaseMapFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNBaseMapFilter.swift; sourceTree = "<group>"; };
|
||||
653C67E125F3CC2E00FE52AC /* EQNCustomAnnotationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNCustomAnnotationView.swift; sourceTree = "<group>"; };
|
||||
653C67FB25F3D63500FE52AC /* EQNMapAnnotationUserReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNMapAnnotationUserReport.swift; sourceTree = "<group>"; };
|
||||
@@ -428,6 +429,7 @@
|
||||
65BBB22B26064BE6005D6CDF /* SegnalazioniLast24HoursCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegnalazioniLast24HoursCell.swift; sourceTree = "<group>"; };
|
||||
65CB83422915720400EE1E35 /* EQNUserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EQNUserData.swift; sourceTree = "<group>"; };
|
||||
65D409932619BA34008CF356 /* SegnalazioniSendReportCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegnalazioniSendReportCell.swift; sourceTree = "<group>"; };
|
||||
65D9938D292264F800F2B0EB /* Foundation+EQNExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Foundation+EQNExtensions.swift"; sourceTree = "<group>"; };
|
||||
65DBFB4A25E29DD60041CBA6 /* SeismicNetworksMapDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeismicNetworksMapDetailViewController.swift; sourceTree = "<group>"; };
|
||||
65DBFB6F25E2BBF20041CBA6 /* GADTMediumTemplateView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GADTMediumTemplateView.xib; sourceTree = "<group>"; };
|
||||
65DBFB7025E2BBF20041CBA6 /* GADTTemplateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GADTTemplateView.h; sourceTree = "<group>"; };
|
||||
@@ -714,7 +716,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8CF66050214C0F7F009F4314 /* Costanti.h */,
|
||||
6535600325F398CD00BB57D2 /* Costanti+Extensions.swift */,
|
||||
8CBD3DC52149B9AD0070C963 /* AppDelegate.h */,
|
||||
8CBD3DC62149B9AD0070C963 /* AppDelegate.m */,
|
||||
DCB6FBEA24D0B11300ED23B8 /* Controllers */,
|
||||
@@ -772,6 +773,7 @@
|
||||
8C7A3B65225A5EA40045B266 /* NSDictionary+EQNExtensions.h */,
|
||||
8C7A3B64225A5EA30045B266 /* NSDictionary+EQNExtensions.m */,
|
||||
65E1B19A260F980600A0ACBA /* Dictionary+EQNExtensions.swift */,
|
||||
65D9938D292264F800F2B0EB /* Foundation+EQNExtensions.swift */,
|
||||
65583A04261B83BE00ECA9F9 /* UIKit+Extensions.swift */,
|
||||
650B23AA2632CCD3007AE752 /* UIView+EQNExtensions.swift */,
|
||||
);
|
||||
@@ -1639,6 +1641,7 @@
|
||||
8C4E34422152B5E8008B0D2A /* EQNRilevamento.m in Sources */,
|
||||
8C7A3B66225A5EA40045B266 /* NSDictionary+EQNExtensions.m in Sources */,
|
||||
8CF66053214C12DC009F4314 /* EQNMath.m in Sources */,
|
||||
65D9938E292264F800F2B0EB /* Foundation+EQNExtensions.swift in Sources */,
|
||||
DCF4A54524F8DB8300B17326 /* SettingDateTableViewCell.swift in Sources */,
|
||||
DC7EEE4A252A11C9004B4A2A /* AlertsSmartphoneNetworkTableViewCell.swift in Sources */,
|
||||
DC7EEE4F252A1634004B4A2A /* AlertsPriorityServiceTableViewCell.swift in Sources */,
|
||||
@@ -1653,7 +1656,6 @@
|
||||
8CBD3DC72149B9AD0070C963 /* AppDelegate.m in Sources */,
|
||||
DC974AFF251748B300A139EC /* SeismicFiltersViewController.swift in Sources */,
|
||||
DC105641251E7ECE002579BB /* UIFont+Extensions.swift in Sources */,
|
||||
6535600425F398CD00BB57D2 /* Costanti+Extensions.swift in Sources */,
|
||||
DCB28CEE24FB8400001F557E /* SettingsViewController.swift in Sources */,
|
||||
DCB528212560161C005288E5 /* AlertSimulatorViewController.swift in Sources */,
|
||||
DCC76BD8251F56050005C4DC /* SeismicCardSettingsViewController.swift in Sources */,
|
||||
@@ -1674,11 +1676,13 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8C465D9F21F7BE0600F04673 /* Assets.xcassets in Sources */,
|
||||
65D9938C2922647800F2B0EB /* AppTheme.swift in Sources */,
|
||||
DC0AE1B92538204100111307 /* EQNSegnalazione.m in Sources */,
|
||||
654D18DE25F943E200BB6DB0 /* EQNMapAnnotationUserReport.swift in Sources */,
|
||||
654D18D625F9420500BB6DB0 /* EQNMapAnnotationPastquake.swift in Sources */,
|
||||
DC0AE1B52538202300111307 /* EQNUtility.m in Sources */,
|
||||
653C67E625F3CC8400FE52AC /* EQNCustomAnnotationView.swift in Sources */,
|
||||
65D9938F2922652100F2B0EB /* Foundation+EQNExtensions.swift in Sources */,
|
||||
654D18DA25F9424700BB6DB0 /* EQNUtility+Extensions.swift in Sources */,
|
||||
DC0AE1BA2538204100111307 /* EQNPastquakes.m in Sources */,
|
||||
65D9938A29219DEC00F2B0EB /* UIKit+Extensions.swift in Sources */,
|
||||
|
||||
@@ -65,6 +65,8 @@ class PasquakesMapViewController: EQNBaseMapViewController {
|
||||
}
|
||||
|
||||
override func didTapAnnotation(_ annotation: MKAnnotation) {
|
||||
mapView.deselectAnnotation(annotation, animated: true)
|
||||
|
||||
guard let annotation = annotation as? EQNMapAnnotationPastquake, let pastquake = annotation.pastquake else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -16,10 +16,74 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
let circle: MKCircle
|
||||
}
|
||||
|
||||
override var isCloseButtonVisible: Bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Contains circles and related colors to draw overlays on the map
|
||||
private var mapCircles = [MapCircle]()
|
||||
/// Reports currently showned on the map
|
||||
private var filteredReports = [EQNSegnalazione]()
|
||||
/// Defines if time has to be shown on map annotations
|
||||
private var showAnnotationTime = false
|
||||
|
||||
// MARK: - UI
|
||||
|
||||
// app icon and name displayed on the screenshot
|
||||
private lazy var watermarkView: UIView = {
|
||||
let view = UIView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.isHidden = true
|
||||
|
||||
let logo = UIImageView(image: .init(named: "eq_icon_transparent"))
|
||||
logo.translatesAutoresizingMaskIntoConstraints = false
|
||||
logo.contentMode = .scaleAspectFit
|
||||
view.addSubview(logo)
|
||||
logo.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||
logo.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
logo.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
||||
logo.widthAnchor.constraint(equalTo: logo.heightAnchor).isActive = true
|
||||
|
||||
let title = UILabel()
|
||||
title.translatesAutoresizingMaskIntoConstraints = false
|
||||
title.text = NSLocalizedString("app_name", comment: "") + " App"
|
||||
title.textColor = AppTheme.Colors.red
|
||||
title.font = .preferredFont(for: .title3, weight: .semibold)
|
||||
view.addSubview(title)
|
||||
title.leadingAnchor.constraint(equalTo: logo.trailingAnchor, constant: 10.0).isActive = true
|
||||
title.centerYAnchor.constraint(equalTo: logo.centerYAnchor).isActive = true
|
||||
title.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var magnitudeLegendView: UIView = {
|
||||
let view = UIView()
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let stackView = UIStackView()
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
stackView.axis = .horizontal
|
||||
stackView.distribution = .fillEqually
|
||||
[20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120].forEach { magnitude in
|
||||
let label = UILabel()
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.text = (magnitude / 10).toRoman()
|
||||
label.backgroundColor = UIColor(named: "Mercalli \(magnitude)")
|
||||
label.textAlignment = .center
|
||||
label.font = .preferredFont(forTextStyle: .callout)
|
||||
label.textColor = magnitude >= 100 ? .white : .black
|
||||
stackView.addArrangedSubview(label)
|
||||
}
|
||||
|
||||
view.addSubview(stackView)
|
||||
stackView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
|
||||
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
|
||||
@@ -29,8 +93,31 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func extraUI() {
|
||||
view.addSubview(magnitudeLegendView)
|
||||
view.addSubview(watermarkView)
|
||||
|
||||
magnitudeLegendView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
magnitudeLegendView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
magnitudeLegendView.heightAnchor.constraint(equalToConstant: 25.0).isActive = true
|
||||
magnitudeLegendView.topAnchor.constraint(equalTo: mapView.topAnchor).isActive = true
|
||||
|
||||
watermarkView.topAnchor.constraint(equalTo: mapView.topAnchor, constant: 10.0).isActive = true
|
||||
watermarkView.leadingAnchor.constraint(equalTo: mapView.leadingAnchor, constant: 10.0).isActive = true
|
||||
watermarkView.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
|
||||
}
|
||||
|
||||
override func configureUI() {
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(onTapCloseButton(_:)))
|
||||
navigationItem.rightBarButtonItems = [
|
||||
UIBarButtonItem(image: UIImage(named: "navbar-icon-screenshot"), style: .plain, target: self, action: #selector(onTapScreenshotButton(_:))),
|
||||
UIBarButtonItem(image: UIImage(named: "navbar-icon-pin-arrow"), style: .plain, target: self, action: #selector(onTapMapDetailStyleButton(_:)))
|
||||
]
|
||||
}
|
||||
|
||||
override func registerMapAnnotationViews() {
|
||||
mapView.register(EQNCustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNCustomAnnotationView.SingleLineIdentifier)
|
||||
mapView.register(EQNCustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: EQNCustomAnnotationView.SmallIdentifier)
|
||||
}
|
||||
|
||||
override func loadDataSource() {
|
||||
@@ -96,27 +183,41 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
}
|
||||
}
|
||||
|
||||
override func didTapAnnotation(_ annotation: MKAnnotation) {
|
||||
guard let annotation = annotation as? EQNMapAnnotationUserReport, let report = annotation.report else {
|
||||
return
|
||||
// MARK: - Actions
|
||||
|
||||
@objc private func onTapCloseButton(_ sender: Any) {
|
||||
dismiss(animated: true)
|
||||
}
|
||||
|
||||
@objc private func onTapMapDetailStyleButton(_ sender: Any) {
|
||||
showAnnotationTime.toggle()
|
||||
loadDataSource()
|
||||
}
|
||||
|
||||
@objc private func onTapScreenshotButton(_ sender: Any) {
|
||||
let snapshot = createSnapshot()
|
||||
|
||||
let controller = UIActivityViewController(activityItems: [snapshot], applicationActivities: [])
|
||||
present(controller, animated: true)
|
||||
}
|
||||
|
||||
public func createSnapshot() -> UIImage {
|
||||
// mostriamo il watermark e nascondiamo la legenda
|
||||
watermarkView.isHidden = false
|
||||
magnitudeLegendView.isHidden = true
|
||||
|
||||
// riduciamo la porzione da salvare alla sola mappa (eliminiamo i filtri)
|
||||
let size = CGSize(width: view.bounds.width, height: mapView.bounds.maxY)
|
||||
let renderer = UIGraphicsImageRenderer(size: size)
|
||||
let image = renderer.image { ctx in
|
||||
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
|
||||
}
|
||||
|
||||
let difference = Int(Date().timeIntervalSince(report.date) / 60.0)
|
||||
let title = EQNUtility.formattedString(forTimeDifference: difference) + " - \(report.intensity.description)"
|
||||
// torniamo allo stato originale
|
||||
watermarkView.isHidden = true
|
||||
magnitudeLegendView.isHidden = false
|
||||
|
||||
var message = ""
|
||||
+ "🏢 " + report.address
|
||||
+ "\n⏱ " + EQNUtility.formattedDate(from: report.date) + " \(NSLocalizedString("share_yourtime", comment: ""))"
|
||||
if !report.message.isEmpty {
|
||||
message += "\n💬 \(report.message)"
|
||||
}
|
||||
|
||||
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("main_share", comment: ""), style: .default, handler: { [unowned self] _ in
|
||||
self.openShareActivity(for: report)
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("official_close", comment: ""), style: .cancel, handler: nil))
|
||||
present(alert, animated: true, completion: nil)
|
||||
return image
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
@@ -125,7 +226,7 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
let vector_latitude = reports.map { $0.coordinate.coordinate.latitude }
|
||||
let vector_longitude = reports.map { $0.coordinate.coordinate.longitude }
|
||||
let vector_date = reports.map { $0.date }
|
||||
let vector_state = reports.map { $0.intensity.rawValue }
|
||||
let vector_state = reports.map { $0.intensity }
|
||||
|
||||
let minutes: TimeInterval = filter.minutes
|
||||
|
||||
@@ -200,21 +301,7 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
}
|
||||
|
||||
let circles = Array(0..<cluster_code).map { (i) -> MapCircle in
|
||||
var value_distance = max_distance[i] / 20.0
|
||||
if value_distance > 1.0 {
|
||||
value_distance = 1.0
|
||||
}
|
||||
let value_intensity = (cluster_intensity[i]-1.0) / 2.0
|
||||
let value_reference = max(value_distance, value_intensity)
|
||||
|
||||
let color: UIColor
|
||||
if value_reference <= 0.5 {
|
||||
let red = round(value_reference * 510)
|
||||
color = UIColor(red: CGFloat(red / 255.0), green: 230.0/255.0, blue: 0.0, alpha: 1.0)
|
||||
} else {
|
||||
let green = round(230 - (value_reference - 0.5) * 460)
|
||||
color = UIColor(red: 255.0, green: CGFloat(green / 255.0), blue: 0.0, alpha: 1.0)
|
||||
}
|
||||
let color: UIColor = AppTheme.Colors.darkGray
|
||||
|
||||
let centre = CLLocation(latitude: lat_centre[i], longitude: lon_centre[i])
|
||||
let farest = CLLocation(latitude: lat_farest[i], longitude: lon_farest[i])
|
||||
@@ -244,25 +331,6 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
Date().timeIntervalSince(date) / 60.0
|
||||
}
|
||||
|
||||
private func openShareActivity(for report: EQNSegnalazione) {
|
||||
// create message to share
|
||||
let intensity = report.intensity.description
|
||||
let difference = Int(Date().timeIntervalSince(report.date) / 60.0)
|
||||
let time = EQNUtility.formattedString(forTimeDifference: difference)
|
||||
|
||||
let message = [
|
||||
NSLocalizedString("share_hashtag", comment: ""),
|
||||
intensity,
|
||||
NSLocalizedString("share_felt", comment: ""),
|
||||
report.address,
|
||||
time + ".",
|
||||
NSLocalizedString("share_notified", comment: "")
|
||||
].joined(separator: " ")
|
||||
|
||||
let controller = UIActivityViewController(activityItems: [message], applicationActivities: [])
|
||||
present(controller, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Map
|
||||
|
||||
override func setupAnnotationView(for annotation: MKAnnotation, on mapView: MKMapView) -> MKAnnotationView? {
|
||||
@@ -270,10 +338,12 @@ class SegnalazioniMapViewController: EQNBaseMapViewController {
|
||||
return nil
|
||||
}
|
||||
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: EQNCustomAnnotationView.SingleLineIdentifier, for: annotation) as! EQNCustomAnnotationView
|
||||
let identifier = showAnnotationTime ? EQNCustomAnnotationView.SingleLineIdentifier : EQNCustomAnnotationView.SmallIdentifier
|
||||
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as! EQNCustomAnnotationView
|
||||
|
||||
annotationView.image = annotation.image
|
||||
annotationView.title = annotation.title
|
||||
annotationView.title = annotation.timeDifference
|
||||
annotationView.canShowCallout = true
|
||||
|
||||
return annotationView
|
||||
}
|
||||
|
||||
@@ -91,7 +91,8 @@
|
||||
- (IBAction)openMapTapped:(id)sender
|
||||
{
|
||||
SegnalazioniMapViewController *controller = [[SegnalazioniMapViewController alloc] init];
|
||||
[self presentViewController:controller animated:YES completion:nil];
|
||||
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
|
||||
[self presentViewController:navController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (IBAction)openTwitterTapped:(id)sender
|
||||
|
||||
@@ -107,6 +107,8 @@ class SeismicNetworksMapDetailViewController: EQNBaseMapViewController {
|
||||
}
|
||||
|
||||
override func didTapAnnotation(_ annotation: MKAnnotation) {
|
||||
mapView.deselectAnnotation(annotation, animated: true)
|
||||
|
||||
guard let annotation = annotation as? EQNMapAnnotationSeismic else { return }
|
||||
|
||||
let viewModel = SeismicNetworkViewModel(seismic: annotation.seismic)
|
||||
|
||||
@@ -27,6 +27,11 @@ class EQNBaseMapViewController: EQNBaseViewController, MKMapViewDelegate {
|
||||
!availableFilters.isEmpty
|
||||
}
|
||||
|
||||
/// If `true` the close button will be shown on top of the map view
|
||||
var isCloseButtonVisible: Bool {
|
||||
true
|
||||
}
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
/// Annotations displayed on the map
|
||||
@@ -116,13 +121,14 @@ class EQNBaseMapViewController: EQNBaseViewController, MKMapViewDelegate {
|
||||
private func setupUI() {
|
||||
view.backgroundColor = .white
|
||||
view.addSubview(mapView)
|
||||
view.addSubview(closeButton)
|
||||
view.addSubview(containerView)
|
||||
if isFilterViewVisible {
|
||||
view.addSubview(filtersView)
|
||||
}
|
||||
|
||||
closeButton.addDefaultConstraint(to: view)
|
||||
if isCloseButtonVisible {
|
||||
view.addSubview(closeButton)
|
||||
closeButton.addDefaultConstraint(to: view)
|
||||
}
|
||||
|
||||
containerView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor).isActive = true
|
||||
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
@@ -145,6 +151,8 @@ class EQNBaseMapViewController: EQNBaseViewController, MKMapViewDelegate {
|
||||
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
|
||||
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
|
||||
mapView.bottomAnchor.constraint(equalTo: (isFilterViewVisible ? filtersView : containerView).topAnchor).isActive = true
|
||||
|
||||
extraUI()
|
||||
}
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
@@ -152,6 +160,7 @@ class EQNBaseMapViewController: EQNBaseViewController, MKMapViewDelegate {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
configureUI()
|
||||
registerMapAnnotationViews()
|
||||
loadDataSource()
|
||||
}
|
||||
@@ -167,6 +176,16 @@ class EQNBaseMapViewController: EQNBaseViewController, MKMapViewDelegate {
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
/// Add extra UI not available in the base class
|
||||
func extraUI() {
|
||||
// nope, subclass will implement some logic
|
||||
}
|
||||
|
||||
/// Configure UI after view initialization
|
||||
func configureUI() {
|
||||
// nope, subclass will implement some logic
|
||||
}
|
||||
|
||||
/// Load data to display on the map
|
||||
func loadDataSource() {
|
||||
// nope, subclass will implement some logic
|
||||
@@ -277,7 +296,5 @@ class EQNBaseMapViewController: EQNBaseViewController, MKMapViewDelegate {
|
||||
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
|
||||
guard let annotation = view.annotation else { return }
|
||||
didTapAnnotation(annotation)
|
||||
|
||||
mapView.deselectAnnotation(annotation, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// Costanti+Extensions.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 06/03/21.
|
||||
// Copyright © 2021 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
extension EQNPastquakeIntensity {
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .mild: return NSLocalizedString("widget_mild", comment: "")
|
||||
case .strong: return NSLocalizedString("widget_strong", comment: "")
|
||||
case .veryStrong: return NSLocalizedString("widget_verystring", comment: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ static NSString * const EQNServerUrlDownloadAreaCheck = @"https://srv.earthquake
|
||||
// download pastquakes
|
||||
static NSString * const EQNServerUrlDownloadPastQuakes = @"https://srv.earthquakenetwork.it/distquake_download_pastquakes.php";
|
||||
// download segnalazioni
|
||||
static NSString * const EQNServerUrlDownloadUserReports = @"https://srv.earthquakenetwork.it/distquake_download_manual.php";
|
||||
static NSString * const EQNServerUrlDownloadUserReports = @"https://srv.earthquakenetwork.it/distquake_download_manual3.php";
|
||||
// Invio segnalazione
|
||||
static NSString * const EQNServerUrlSendUserReport = @"https://srv.earthquakenetwork.it/distquake_upload_manual4.php";
|
||||
static NSString * const EQNServerUrlSendUserReportMessage = @"https://srv.earthquakenetwork.it/distquake_upload_manual_message.php";
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Foundation+EQNExtensions.swift
|
||||
// Earthquake Network
|
||||
//
|
||||
// Created by Andrea Busi on 14/11/22.
|
||||
// Copyright © 2022 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
extension Int {
|
||||
func toRoman() -> String {
|
||||
let conversionTable: [(intNumber: Int, romanNumber: String)] =
|
||||
[(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"),
|
||||
(90, "XC"), (50, "L"), (40, "XL"), (10, "X"),
|
||||
(9, "IX"), (5, "V"), (4, "IV"), (1, "I")]
|
||||
var roman = ""
|
||||
var remainder = 0
|
||||
|
||||
for entry in conversionTable {
|
||||
let quotient = (self - remainder) / entry.intNumber
|
||||
remainder += quotient * entry.intNumber
|
||||
roman += String(repeating: entry.romanNumber, count: quotient)
|
||||
}
|
||||
|
||||
return roman
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,32 @@ extension UIButton {
|
||||
}
|
||||
|
||||
|
||||
extension UIImage {
|
||||
class func circle(
|
||||
diameter: CGFloat,
|
||||
color: UIColor,
|
||||
borderWidth: CGFloat = 0.0,
|
||||
borderColor: UIColor = .black
|
||||
) -> UIImage {
|
||||
let size = CGSize(width: diameter, height: diameter)
|
||||
let renderer = UIGraphicsImageRenderer(size: size)
|
||||
let img = renderer.image { ctx in
|
||||
ctx.cgContext.setFillColor(color.cgColor)
|
||||
ctx.cgContext.setStrokeColor(borderColor.cgColor)
|
||||
ctx.cgContext.setLineWidth(borderWidth)
|
||||
|
||||
// reduce circle size to keep space for the border
|
||||
// without this, the image view is cropped
|
||||
let circleDiameter = diameter - 2*borderWidth
|
||||
let rectangle = CGRect(x: borderWidth, y: borderWidth, width: circleDiameter, height: circleDiameter)
|
||||
ctx.cgContext.addEllipse(in: rectangle)
|
||||
ctx.cgContext.drawPath(using: .fillStroke)
|
||||
}
|
||||
return img
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension UIView {
|
||||
/// Creates a snapshot of the current view
|
||||
/// - Returns: Image with the snapshot of the view
|
||||
|
||||
@@ -9,23 +9,15 @@
|
||||
@import Foundation;
|
||||
@import CoreLocation;
|
||||
|
||||
// Intensità terremoti segnalazioni utente
|
||||
typedef NS_CLOSED_ENUM(NSInteger, EQNPastquakeIntensity) {
|
||||
EQNPastquakeIntensityMild = 1,
|
||||
EQNPastquakeIntensityStrong = 2,
|
||||
EQNPastquakeIntensityVeryStrong = 3
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EQNSegnalazione : NSObject
|
||||
|
||||
@property (nonatomic, strong) CLLocation *coordinate;
|
||||
@property (nonatomic, strong) NSString *address;
|
||||
@property (nonatomic, strong) NSDate *date;
|
||||
@property (nonatomic) NSInteger difference;
|
||||
@property (nonatomic) EQNPastquakeIntensity intensity;
|
||||
@property (nonatomic, strong) NSString *message;
|
||||
// values are from 20 to 120
|
||||
@property (nonatomic) NSInteger intensity;
|
||||
|
||||
- (instancetype)initWithDictionary:(NSDictionary *)dictionary;
|
||||
|
||||
|
||||
@@ -17,15 +17,12 @@
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
double latitude = [dictionary[@"latitude"] doubleValue];
|
||||
double longitude = [dictionary[@"longitude"] doubleValue];
|
||||
double latitude = [dictionary[@"la"] doubleValue];
|
||||
double longitude = [dictionary[@"lo"] doubleValue];
|
||||
_coordinate = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
|
||||
_address = dictionary[@"address"];
|
||||
NSDate *date = [EQNUtility getDateFromString:dictionary[@"date"]];
|
||||
NSDate *date = [EQNUtility getDateFromString:dictionary[@"dt"]];
|
||||
_date = date == nil ? [NSDate date] : date;
|
||||
_difference = [dictionary[@"difference"] integerValue];
|
||||
_intensity = [dictionary[@"magnitude"] integerValue];
|
||||
_message = dictionary[@"msg"];
|
||||
_intensity = [dictionary[@"ma"] integerValue];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -34,24 +31,18 @@
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)encoder
|
||||
{
|
||||
[encoder encodeObject:self.address forKey:@"address"];
|
||||
[encoder encodeObject:self.date forKey:@"date"];
|
||||
[encoder encodeInteger:self.difference forKey:@"difference"];
|
||||
[encoder encodeObject:self.coordinate forKey:@"coordinate"];
|
||||
[encoder encodeInteger:self.intensity forKey:@"intensity"];
|
||||
[encoder encodeObject:self.message forKey:@"message"];
|
||||
}
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)decoder
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.address = [decoder decodeObjectForKey:@"address"];
|
||||
self.date = [decoder decodeObjectForKey:@"date"];
|
||||
self.difference = [decoder decodeIntegerForKey:@"difference"];
|
||||
self.coordinate = [decoder decodeObjectForKey:@"coordinate"];
|
||||
self.intensity = [decoder decodeIntegerForKey:@"intensity"];
|
||||
self.message = [decoder decodeObjectForKey:@"message"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -15,36 +15,60 @@ class EQNMapAnnotationUserReport: NSObject, MKAnnotation {
|
||||
|
||||
@objc var coordinate: CLLocationCoordinate2D
|
||||
@objc var title: String?
|
||||
@objc var subtitle: String?
|
||||
@objc var image: UIImage?
|
||||
@objc var timeDifference: String?
|
||||
|
||||
var report: EQNSegnalazione?
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
convenience init(report: EQNSegnalazione) {
|
||||
let coordinate = CLLocationCoordinate2D(latitude: report.coordinate.coordinate.latitude, longitude: report.coordinate.coordinate.longitude)
|
||||
let magnitude = report.intensity.rawValue
|
||||
let title = EQNUtility.formattedTimeDifference(from: report.date)
|
||||
let coordinate = report.coordinate.coordinate
|
||||
let magnitude = report.intensity
|
||||
|
||||
self.init(title: title, coordinate: coordinate, magnitude: magnitude)
|
||||
self.init(magnitude: magnitude, coordinate: coordinate)
|
||||
self.report = report
|
||||
self.timeDifference = EQNUtility.formattedTimeDifference(from: report.date)
|
||||
}
|
||||
|
||||
@objc init(title: String, coordinate: CLLocationCoordinate2D, magnitude: Int) {
|
||||
self.title = title
|
||||
self.image = Self.image(for: magnitude)
|
||||
@objc init(
|
||||
magnitude: Int,
|
||||
coordinate: CLLocationCoordinate2D
|
||||
) {
|
||||
self.title = Self.title(for: magnitude)
|
||||
self.subtitle = Self.subtitle(for: magnitude)
|
||||
self.coordinate = coordinate
|
||||
super.init()
|
||||
self.image = Self.image(for: magnitude)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
// MARK: - Helper
|
||||
|
||||
private static func image(for magnitute: Int) -> UIImage? {
|
||||
switch magnitute {
|
||||
case 1: return UIImage(named: "star_report_green")
|
||||
case 2: return UIImage(named: "star_report_yellow")
|
||||
case 3: return UIImage(named: "star_report_red")
|
||||
default: return nil
|
||||
guard let color = UIColor(named: "Mercalli \(magnitute)") else {
|
||||
print("[EQNMapAnnotationUserReport] Unable to get a color for magnitude: \(magnitute)")
|
||||
return nil
|
||||
}
|
||||
|
||||
return UIImage.circle(diameter: 24.0, color: color, borderWidth: 1.0, borderColor: AppTheme.Colors.gray)
|
||||
}
|
||||
|
||||
private static func title(for magnitude: Int) -> String {
|
||||
let grade = magnitude / 10
|
||||
let roman = grade.toRoman()
|
||||
return String(format: NSLocalizedString("mercalli_intensity", comment: ""), roman)
|
||||
}
|
||||
|
||||
private static func subtitle(for magnitude: Int) -> String {
|
||||
let grade = magnitude / 10
|
||||
let roman = grade.toRoman()
|
||||
let string = NSLocalizedString("mercalli_\(roman)", comment: "")
|
||||
// strings are in the format like "II - Appena percepito"
|
||||
// so we are going to remove the "II" from the string
|
||||
let components = string.components(separatedBy: " - ")
|
||||
if components.count > 1 {
|
||||
return components[1]
|
||||
}
|
||||
return string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "eq_icon_transparent.png",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "navbar-icon-pin-arrow.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "navbar-icon-pin-arrow@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "navbar-icon-pin-arrow@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 596 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "navbar-icon-screenshot.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "navbar-icon-screenshot@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "navbar-icon-screenshot@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 296 B |
|
After Width: | Height: | Size: 423 B |
|
After Width: | Height: | Size: 594 B |
@@ -6,7 +6,7 @@
|
||||
// Copyright © 2020 Earthquake Network. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
|
||||
@objcMembers
|
||||
|
||||
@@ -13,6 +13,7 @@ import MapKit
|
||||
@objc
|
||||
public class EQNCustomAnnotationView: MKAnnotationView {
|
||||
|
||||
@objc static let SmallIdentifier = "EQNCustomAnnotationViewSmall"
|
||||
@objc static let SingleLineIdentifier = "EQNCustomAnnotationViewSingleLine"
|
||||
@objc static let DoubleLineIdentifier = "EQNCustomAnnotationViewDoubleLine"
|
||||
|
||||
@@ -67,9 +68,12 @@ public class EQNCustomAnnotationView: MKAnnotationView {
|
||||
|
||||
backgroundColor = .clear
|
||||
|
||||
if reuseIdentifier == Self.SingleLineIdentifier {
|
||||
if reuseIdentifier == Self.SmallIdentifier {
|
||||
frame = CGRect(x: 0, y: 0, width: 16, height: 16)
|
||||
setupSmallUI()
|
||||
} else if reuseIdentifier == Self.SingleLineIdentifier {
|
||||
frame = CGRect(x: 0, y: 0, width: 40, height: 40)
|
||||
setupUI()
|
||||
setupSingleLineUI()
|
||||
} else if reuseIdentifier == Self.DoubleLineIdentifier {
|
||||
frame = CGRect(x: 0, y: 0, width: 40, height: 55)
|
||||
setupDoubleLineUI()
|
||||
@@ -82,7 +86,12 @@ public class EQNCustomAnnotationView: MKAnnotationView {
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func setupUI() {
|
||||
private func setupSmallUI() {
|
||||
imageView.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
|
||||
addSubview(imageView)
|
||||
}
|
||||
|
||||
private func setupSingleLineUI() {
|
||||
let labelFrame = CGRect(x: 0, y: 0, width: frame.width, height: Self.HeightLabel)
|
||||
labelTop.frame = labelFrame
|
||||
addSubview(labelTop)
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"mercalli_X" = "X - Ολόκληρα κτίρια κατέρρευσαν";
|
||||
"mercalli_XI" = "XI - Καταστροφές ολόκληρων αστικών κέντρων, πολλά θύματα, ρωγμές στο έδαφος και κατολισθήσεις";
|
||||
"mercalli_XII" = "XII - Διάσπαση του εδάφους, μετατόπιση του φλοιού της γης";
|
||||
"mercalli_intensity" = "Ένταση %@";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Μέγεθος >= 0.0";
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"mercalli_X" = "X - Whole buildings collapsed";
|
||||
"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 %@";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitude >= 0.0";
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"mercalli_X" = "X - Edificios enteros se derrumbaron";
|
||||
"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 %@";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitud >= 0.0";
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"mercalli_X" = "X - Des bâtiments entiers se sont effondrés";
|
||||
"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é %@";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitude >= 0.0";
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"mercalli_X" = "X - Čitave zgrade srušene";
|
||||
"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 %@";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Jačina >= 0.0";
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"mercalli_X" = "X - Seluruh bangunan runtuh";
|
||||
"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 %@";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitudo >= 0.0";
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"mercalli_X" = "X - Interi edifici crollati";
|
||||
"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à %@";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Magnitudo >= 0.0";
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"mercalli_X" = "X - Bütün binalar çöktü";
|
||||
"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 %@";
|
||||
|
||||
// values
|
||||
"official_magnitude_value_00" = "Büyüklük >= 0.0";
|
||||
|
||||